Home | History | Annotate | Download | only in tests
      1 /*
      2  ** Copyright 2011, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <utils/BlobCache.h>
     20 
     21 namespace android {
     22 
     23 class BlobCacheTest : public ::testing::Test {
     24 protected:
     25     enum {
     26         MAX_KEY_SIZE = 6,
     27         MAX_VALUE_SIZE = 8,
     28         MAX_TOTAL_SIZE = 13,
     29     };
     30 
     31     virtual void SetUp() {
     32         mBC = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE);
     33     }
     34 
     35     virtual void TearDown() {
     36         mBC.clear();
     37     }
     38 
     39     sp<BlobCache> mBC;
     40 };
     41 
     42 TEST_F(BlobCacheTest, CacheSingleValueSucceeds) {
     43     char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     44     mBC->set("abcd", 4, "efgh", 4);
     45     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
     46     ASSERT_EQ('e', buf[0]);
     47     ASSERT_EQ('f', buf[1]);
     48     ASSERT_EQ('g', buf[2]);
     49     ASSERT_EQ('h', buf[3]);
     50 }
     51 
     52 TEST_F(BlobCacheTest, CacheTwoValuesSucceeds) {
     53     char buf[2] = { 0xee, 0xee };
     54     mBC->set("ab", 2, "cd", 2);
     55     mBC->set("ef", 2, "gh", 2);
     56     ASSERT_EQ(size_t(2), mBC->get("ab", 2, buf, 2));
     57     ASSERT_EQ('c', buf[0]);
     58     ASSERT_EQ('d', buf[1]);
     59     ASSERT_EQ(size_t(2), mBC->get("ef", 2, buf, 2));
     60     ASSERT_EQ('g', buf[0]);
     61     ASSERT_EQ('h', buf[1]);
     62 }
     63 
     64 TEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) {
     65     char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
     66     mBC->set("abcd", 4, "efgh", 4);
     67     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf+1, 4));
     68     ASSERT_EQ(0xee, buf[0]);
     69     ASSERT_EQ('e', buf[1]);
     70     ASSERT_EQ('f', buf[2]);
     71     ASSERT_EQ('g', buf[3]);
     72     ASSERT_EQ('h', buf[4]);
     73     ASSERT_EQ(0xee, buf[5]);
     74 }
     75 
     76 TEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {
     77     char buf[3] = { 0xee, 0xee, 0xee };
     78     mBC->set("abcd", 4, "efgh", 4);
     79     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 3));
     80     ASSERT_EQ(0xee, buf[0]);
     81     ASSERT_EQ(0xee, buf[1]);
     82     ASSERT_EQ(0xee, buf[2]);
     83 }
     84 
     85 TEST_F(BlobCacheTest, GetDoesntAccessNullBuffer) {
     86     mBC->set("abcd", 4, "efgh", 4);
     87     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, NULL, 0));
     88 }
     89 
     90 TEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) {
     91     char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     92     mBC->set("abcd", 4, "efgh", 4);
     93     mBC->set("abcd", 4, "ijkl", 4);
     94     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
     95     ASSERT_EQ('i', buf[0]);
     96     ASSERT_EQ('j', buf[1]);
     97     ASSERT_EQ('k', buf[2]);
     98     ASSERT_EQ('l', buf[3]);
     99 }
    100 
    101 TEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {
    102     char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };
    103     mBC->set("abcd", 4, "efgh", 4);
    104     mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
    105     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
    106     ASSERT_EQ('e', buf[0]);
    107     ASSERT_EQ('f', buf[1]);
    108     ASSERT_EQ('g', buf[2]);
    109     ASSERT_EQ('h', buf[3]);
    110 }
    111 
    112 TEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) {
    113     char key[MAX_KEY_SIZE+1];
    114     char buf[4] = { 0xee, 0xee, 0xee, 0xee };
    115     for (int i = 0; i < MAX_KEY_SIZE+1; i++) {
    116         key[i] = 'a';
    117     }
    118     mBC->set(key, MAX_KEY_SIZE+1, "bbbb", 4);
    119     ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE+1, buf, 4));
    120     ASSERT_EQ(0xee, buf[0]);
    121     ASSERT_EQ(0xee, buf[1]);
    122     ASSERT_EQ(0xee, buf[2]);
    123     ASSERT_EQ(0xee, buf[3]);
    124 }
    125 
    126 TEST_F(BlobCacheTest, DoesntCacheIfValueIsTooBig) {
    127     char buf[MAX_VALUE_SIZE+1];
    128     for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
    129         buf[i] = 'b';
    130     }
    131     mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
    132     for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
    133         buf[i] = 0xee;
    134     }
    135     ASSERT_EQ(size_t(0), mBC->get("abcd", 4, buf, MAX_VALUE_SIZE+1));
    136     for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
    137         SCOPED_TRACE(i);
    138         ASSERT_EQ(0xee, buf[i]);
    139     }
    140 }
    141 
    142 TEST_F(BlobCacheTest, DoesntCacheIfKeyValuePairIsTooBig) {
    143     // Check a testing assumptions
    144     ASSERT_TRUE(MAX_TOTAL_SIZE < MAX_KEY_SIZE + MAX_VALUE_SIZE);
    145     ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
    146 
    147     enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE + 1 };
    148 
    149     char key[MAX_KEY_SIZE];
    150     char buf[bufSize];
    151     for (int i = 0; i < MAX_KEY_SIZE; i++) {
    152         key[i] = 'a';
    153     }
    154     for (int i = 0; i < bufSize; i++) {
    155         buf[i] = 'b';
    156     }
    157 
    158     mBC->set(key, MAX_KEY_SIZE, buf, MAX_VALUE_SIZE);
    159     ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
    160 }
    161 
    162 TEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) {
    163     char key[MAX_KEY_SIZE];
    164     char buf[4] = { 0xee, 0xee, 0xee, 0xee };
    165     for (int i = 0; i < MAX_KEY_SIZE; i++) {
    166         key[i] = 'a';
    167     }
    168     mBC->set(key, MAX_KEY_SIZE, "wxyz", 4);
    169     ASSERT_EQ(size_t(4), mBC->get(key, MAX_KEY_SIZE, buf, 4));
    170     ASSERT_EQ('w', buf[0]);
    171     ASSERT_EQ('x', buf[1]);
    172     ASSERT_EQ('y', buf[2]);
    173     ASSERT_EQ('z', buf[3]);
    174 }
    175 
    176 TEST_F(BlobCacheTest, CacheMaxValueSizeSucceeds) {
    177     char buf[MAX_VALUE_SIZE];
    178     for (int i = 0; i < MAX_VALUE_SIZE; i++) {
    179         buf[i] = 'b';
    180     }
    181     mBC->set("abcd", 4, buf, MAX_VALUE_SIZE);
    182     for (int i = 0; i < MAX_VALUE_SIZE; i++) {
    183         buf[i] = 0xee;
    184     }
    185     ASSERT_EQ(size_t(MAX_VALUE_SIZE), mBC->get("abcd", 4, buf,
    186             MAX_VALUE_SIZE));
    187     for (int i = 0; i < MAX_VALUE_SIZE; i++) {
    188         SCOPED_TRACE(i);
    189         ASSERT_EQ('b', buf[i]);
    190     }
    191 }
    192 
    193 TEST_F(BlobCacheTest, CacheMaxKeyValuePairSizeSucceeds) {
    194     // Check a testing assumption
    195     ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
    196 
    197     enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE };
    198 
    199     char key[MAX_KEY_SIZE];
    200     char buf[bufSize];
    201     for (int i = 0; i < MAX_KEY_SIZE; i++) {
    202         key[i] = 'a';
    203     }
    204     for (int i = 0; i < bufSize; i++) {
    205         buf[i] = 'b';
    206     }
    207 
    208     mBC->set(key, MAX_KEY_SIZE, buf, bufSize);
    209     ASSERT_EQ(size_t(bufSize), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
    210 }
    211 
    212 TEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
    213     char buf[1] = { 0xee };
    214     mBC->set("x", 1, "y", 1);
    215     ASSERT_EQ(size_t(1), mBC->get("x", 1, buf, 1));
    216     ASSERT_EQ('y', buf[0]);
    217 }
    218 
    219 TEST_F(BlobCacheTest, CacheSizeDoesntExceedTotalLimit) {
    220     for (int i = 0; i < 256; i++) {
    221         uint8_t k = i;
    222         mBC->set(&k, 1, "x", 1);
    223     }
    224     int numCached = 0;
    225     for (int i = 0; i < 256; i++) {
    226         uint8_t k = i;
    227         if (mBC->get(&k, 1, NULL, 0) == 1) {
    228             numCached++;
    229         }
    230     }
    231     ASSERT_GE(MAX_TOTAL_SIZE / 2, numCached);
    232 }
    233 
    234 TEST_F(BlobCacheTest, ExceedingTotalLimitHalvesCacheSize) {
    235     // Fill up the entire cache with 1 char key/value pairs.
    236     const int maxEntries = MAX_TOTAL_SIZE / 2;
    237     for (int i = 0; i < maxEntries; i++) {
    238         uint8_t k = i;
    239         mBC->set(&k, 1, "x", 1);
    240     }
    241     // Insert one more entry, causing a cache overflow.
    242     {
    243         uint8_t k = maxEntries;
    244         mBC->set(&k, 1, "x", 1);
    245     }
    246     // Count the number of entries in the cache.
    247     int numCached = 0;
    248     for (int i = 0; i < maxEntries+1; i++) {
    249         uint8_t k = i;
    250         if (mBC->get(&k, 1, NULL, 0) == 1) {
    251             numCached++;
    252         }
    253     }
    254     ASSERT_EQ(maxEntries/2 + 1, numCached);
    255 }
    256 
    257 } // namespace android
    258