1b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian/*
2b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** Copyright 2011, The Android Open Source Project
3b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian **
4b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License");
5b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** you may not use this file except in compliance with the License.
6b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** You may obtain a copy of the License at
7b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian **
8b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian **     http://www.apache.org/licenses/LICENSE-2.0
9b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian **
10b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** Unless required by applicable law or agreed to in writing, software
11b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS,
12b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** See the License for the specific language governing permissions and
14b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian ** limitations under the License.
15b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian */
16b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
17b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include <fcntl.h>
18b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include <stdio.h>
19b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
20b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include <memory>
21b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
22b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include <gtest/gtest.h>
23b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
24b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include "BlobCache.h"
25b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
26b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopiannamespace android {
27b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
28b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopiantemplate<typename T> using sp = std::shared_ptr<T>;
29b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
30b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianclass BlobCacheTest : public ::testing::Test {
31b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianprotected:
32b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
33b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    enum {
34b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        OK = 0,
35b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        BAD_VALUE = -EINVAL
36b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    };
37b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
38b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    enum {
39b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        MAX_KEY_SIZE = 6,
40b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        MAX_VALUE_SIZE = 8,
41b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        MAX_TOTAL_SIZE = 13,
42b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    };
43b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
44b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    virtual void SetUp() {
45b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC.reset(new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE));
46b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
47b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
48b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    virtual void TearDown() {
49b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC.reset();
50b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
51b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
52b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    std::unique_ptr<BlobCache> mBC;
53b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian};
54b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
55b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheSingleValueSucceeds) {
56b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
57b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
58b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
59b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('e', buf[0]);
60b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('f', buf[1]);
61b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('g', buf[2]);
62b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('h', buf[3]);
63b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
64b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
65b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheTwoValuesSucceeds) {
66b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[2] = { 0xee, 0xee };
67b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("ab", 2, "cd", 2);
68b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("ef", 2, "gh", 2);
69b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(2), mBC->get("ab", 2, buf, 2));
70b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('c', buf[0]);
71b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('d', buf[1]);
72b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(2), mBC->get("ef", 2, buf, 2));
73b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('g', buf[0]);
74b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('h', buf[1]);
75b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
76b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
77b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) {
78b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
79b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
80b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf+1, 4));
81b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[0]);
82b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('e', buf[1]);
83b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('f', buf[2]);
84b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('g', buf[3]);
85b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('h', buf[4]);
86b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[5]);
87b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
88b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
89b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {
90b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[3] = { 0xee, 0xee, 0xee };
91b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
92b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 3));
93b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[0]);
94b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[1]);
95b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[2]);
96b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
97b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
98b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, GetDoesntAccessNullBuffer) {
99b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
100b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, NULL, 0));
101b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
102b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
103b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) {
104b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
105b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
106b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "ijkl", 4);
107b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
108b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('i', buf[0]);
109b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('j', buf[1]);
110b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('k', buf[2]);
111b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('l', buf[3]);
112b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
113b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
114b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {
115b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };
116b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
117b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
118b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
119b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('e', buf[0]);
120b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('f', buf[1]);
121b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('g', buf[2]);
122b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('h', buf[3]);
123b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
124b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
125b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) {
126b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char key[MAX_KEY_SIZE+1];
127b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
128b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_KEY_SIZE+1; i++) {
129b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        key[i] = 'a';
130b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
131b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set(key, MAX_KEY_SIZE+1, "bbbb", 4);
132b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE+1, buf, 4));
133b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[0]);
134b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[1]);
135b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[2]);
136b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(0xee, buf[3]);
137b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
138b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
139b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, DoesntCacheIfValueIsTooBig) {
140b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char buf[MAX_VALUE_SIZE+1];
141b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
142b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 'b';
143b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
144b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
145b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
146b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 0xee;
147b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
148b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC->get("abcd", 4, buf, MAX_VALUE_SIZE+1));
149b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
150b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        SCOPED_TRACE(i);
151b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(0xee, buf[i]);
152b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
153b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
154b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
155b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, DoesntCacheIfKeyValuePairIsTooBig) {
156b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Check a testing assumptions
157b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_TRUE(MAX_TOTAL_SIZE < MAX_KEY_SIZE + MAX_VALUE_SIZE);
158b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
159b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
160b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE + 1 };
161b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
162b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char key[MAX_KEY_SIZE];
163b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char buf[bufSize];
164b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_KEY_SIZE; i++) {
165b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        key[i] = 'a';
166b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
167b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < bufSize; i++) {
168b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 'b';
169b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
170b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
171b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set(key, MAX_KEY_SIZE, buf, MAX_VALUE_SIZE);
172b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
173b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
174b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
175b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) {
176b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char key[MAX_KEY_SIZE];
177b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
178b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_KEY_SIZE; i++) {
179b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        key[i] = 'a';
180b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
181b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set(key, MAX_KEY_SIZE, "wxyz", 4);
182b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC->get(key, MAX_KEY_SIZE, buf, 4));
183b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('w', buf[0]);
184b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('x', buf[1]);
185b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('y', buf[2]);
186b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('z', buf[3]);
187b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
188b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
189b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheMaxValueSizeSucceeds) {
190b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char buf[MAX_VALUE_SIZE];
191b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE; i++) {
192b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 'b';
193b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
194b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, buf, MAX_VALUE_SIZE);
195b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE; i++) {
196b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 0xee;
197b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
198b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(MAX_VALUE_SIZE), mBC->get("abcd", 4, buf,
199b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian            MAX_VALUE_SIZE));
200b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_VALUE_SIZE; i++) {
201b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        SCOPED_TRACE(i);
202b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ('b', buf[i]);
203b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
204b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
205b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
206b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheMaxKeyValuePairSizeSucceeds) {
207b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Check a testing assumption
208b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
209b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
210b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE };
211b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
212b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char key[MAX_KEY_SIZE];
213b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    char buf[bufSize];
214b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < MAX_KEY_SIZE; i++) {
215b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        key[i] = 'a';
216b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
217b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < bufSize; i++) {
218b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        buf[i] = 'b';
219b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
220b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
221b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set(key, MAX_KEY_SIZE, buf, bufSize);
222b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(bufSize), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
223b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
224b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
225b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
226b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[1] = { 0xee };
227b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("x", 1, "y", 1);
228b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(1), mBC->get("x", 1, buf, 1));
229b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('y', buf[0]);
230b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
231b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
232b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, CacheSizeDoesntExceedTotalLimit) {
233b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < 256; i++) {
234b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
235b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, "x", 1);
236b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
237b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    int numCached = 0;
238b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < 256; i++) {
239b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
240b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        if (mBC->get(&k, 1, NULL, 0) == 1) {
241b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian            numCached++;
242b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        }
243b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
244b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_GE(MAX_TOTAL_SIZE / 2, numCached);
245b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
246b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
247b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheTest, ExceedingTotalLimitHalvesCacheSize) {
248b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Fill up the entire cache with 1 char key/value pairs.
249b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    const int maxEntries = MAX_TOTAL_SIZE / 2;
250b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
251b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
252b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, "x", 1);
253b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
254b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Insert one more entry, causing a cache overflow.
255b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    {
256b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = maxEntries;
257b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, "x", 1);
258b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
259b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Count the number of entries in the cache.
260b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    int numCached = 0;
261b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries+1; i++) {
262b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
263b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        if (mBC->get(&k, 1, NULL, 0) == 1) {
264b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian            numCached++;
265b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        }
266b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
267b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(maxEntries/2 + 1, numCached);
268b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
269b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
270b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianclass BlobCacheFlattenTest : public BlobCacheTest {
271b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianprotected:
272b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    virtual void SetUp() {
273b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        BlobCacheTest::SetUp();
274b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC2.reset(new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE));
275b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
276b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
277b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    virtual void TearDown() {
278b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC2.reset();
279b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        BlobCacheTest::TearDown();
280b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
281b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
282b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    void roundTrip() {
283b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        size_t size = mBC->getFlattenedSize();
284b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t* flat = new uint8_t[size];
285b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(OK, mBC->flatten(flat, size));
286b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(OK, mBC2->unflatten(flat, size));
287b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        delete[] flat;
288b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
289b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
290b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    sp<BlobCache> mBC2;
291b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian};
292b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
293b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, FlattenOneValue) {
294b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
295b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
296b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    roundTrip();
297b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(4), mBC2->get("abcd", 4, buf, 4));
298b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('e', buf[0]);
299b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('f', buf[1]);
300b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('g', buf[2]);
301b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ('h', buf[3]);
302b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
303b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
304b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, FlattenFullCache) {
305b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Fill up the entire cache with 1 char key/value pairs.
306b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    const int maxEntries = MAX_TOTAL_SIZE / 2;
307b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
308b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
309b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, &k, 1);
310b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
311b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
312b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    roundTrip();
313b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
314b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Verify the deserialized cache
315b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
316b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
317b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t v = 0xee;
318b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(size_t(1), mBC2->get(&k, 1, &v, 1));
319b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(k, v);
320b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
321b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
322b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
323b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, FlattenDoesntChangeCache) {
324b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Fill up the entire cache with 1 char key/value pairs.
325b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    const int maxEntries = MAX_TOTAL_SIZE / 2;
326b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
327b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
328b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, &k, 1);
329b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
330b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
331b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize();
332b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
333b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC->flatten(flat, size));
334b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
335b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
336b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Verify the cache that we just serialized
337b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
338b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
339b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t v = 0xee;
340b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(size_t(1), mBC->get(&k, 1, &v, 1));
341b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        ASSERT_EQ(k, v);
342b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
343b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
344b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
345b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, FlattenCatchesBufferTooSmall) {
346b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Fill up the entire cache with 1 char key/value pairs.
347b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    const int maxEntries = MAX_TOTAL_SIZE / 2;
348b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    for (int i = 0; i < maxEntries; i++) {
349b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        uint8_t k = i;
350b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian        mBC->set(&k, 1, &k, 1);
351b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    }
352b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
353b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize() - 1;
354b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
355b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // ASSERT_EQ(BAD_VALUE, mBC->flatten(flat, size));
356b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // TODO: The above fails. I expect this is so because getFlattenedSize()
357b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // overstimates the size by using PROPERTY_VALUE_MAX.
358b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
359b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
360b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
361b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadMagic) {
362b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
363b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
364b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
365b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize();
366b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
367b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC->flatten(flat, size));
368b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    flat[1] = ~flat[1];
369b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
370b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Bad magic should cause an error.
371b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size));
372b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
373b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
374b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // The error should cause the unflatten to result in an empty cache
375b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
376b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
377b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
378b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheVersion) {
379b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
380b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
381b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
382b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize();
383b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
384b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC->flatten(flat, size));
385b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    flat[5] = ~flat[5];
386b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
387b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Version mismatches shouldn't cause errors, but should not use the
388b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // serialized entries
389b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC2->unflatten(flat, size));
390b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
391b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
392b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // The version mismatch should cause the unflatten to result in an empty
393b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // cache
394b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
395b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
396b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
397b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheDeviceVersion) {
398b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
399b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
400b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
401b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize();
402b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
403b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC->flatten(flat, size));
404b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    flat[10] = ~flat[10];
405b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
406b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // Version mismatches shouldn't cause errors, but should not use the
407b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // serialized entries
408b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC2->unflatten(flat, size));
409b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
410b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
411b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // The version mismatch should cause the unflatten to result in an empty
412b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // cache
413b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
414b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
415b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
416b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias AgopianTEST_F(BlobCacheFlattenTest, UnflattenCatchesBufferTooSmall) {
417b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
418b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    mBC->set("abcd", 4, "efgh", 4);
419b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
420b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    size_t size = mBC->getFlattenedSize();
421b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    uint8_t* flat = new uint8_t[size];
422b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(OK, mBC->flatten(flat, size));
423b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
424b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // A buffer truncation shouldt cause an error
425b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size-1));
426b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // TODO: The above appears to fail because getFlattenedSize() is
427b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // conservative.
428b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    delete[] flat;
429b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
430b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    // The error should cause the unflatten to result in an empty cache
431b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
432b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
433b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
434b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian} // namespace android
435