xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/MemoryCacheTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
18*eb293b8fSAndroid Build Coastguard Worker 
19*eb293b8fSAndroid Build Coastguard Worker #include <vector>
20*eb293b8fSAndroid Build Coastguard Worker 
21*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*eb293b8fSAndroid Build Coastguard Worker 
23*eb293b8fSAndroid Build Coastguard Worker #include "MemoryCache.h"
24*eb293b8fSAndroid Build Coastguard Worker #include "utils/MemoryFake.h"
25*eb293b8fSAndroid Build Coastguard Worker 
26*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
27*eb293b8fSAndroid Build Coastguard Worker 
28*eb293b8fSAndroid Build Coastguard Worker class MemoryCacheTest : public ::testing::Test {
29*eb293b8fSAndroid Build Coastguard Worker  protected:
SetUp()30*eb293b8fSAndroid Build Coastguard Worker   void SetUp() override {
31*eb293b8fSAndroid Build Coastguard Worker     memory_ = new MemoryFake;
32*eb293b8fSAndroid Build Coastguard Worker     memory_cache_.reset(new MemoryCache(memory_));
33*eb293b8fSAndroid Build Coastguard Worker 
34*eb293b8fSAndroid Build Coastguard Worker     memory_->SetMemoryBlock(0x8000, 4096, 0xab);
35*eb293b8fSAndroid Build Coastguard Worker     memory_->SetMemoryBlock(0x9000, 4096, 0xde);
36*eb293b8fSAndroid Build Coastguard Worker     memory_->SetMemoryBlock(0xa000, 3000, 0x50);
37*eb293b8fSAndroid Build Coastguard Worker   }
38*eb293b8fSAndroid Build Coastguard Worker 
39*eb293b8fSAndroid Build Coastguard Worker   MemoryFake* memory_;
40*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<MemoryCache> memory_cache_;
41*eb293b8fSAndroid Build Coastguard Worker 
42*eb293b8fSAndroid Build Coastguard Worker   constexpr static size_t kMaxCachedSize = 64;
43*eb293b8fSAndroid Build Coastguard Worker };
44*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,cached_read)45*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, cached_read) {
46*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 1; i <= kMaxCachedSize; i++) {
47*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
48*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
49*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
50*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xab), buffer) << "Failed at size " << i;
51*eb293b8fSAndroid Build Coastguard Worker   }
52*eb293b8fSAndroid Build Coastguard Worker 
53*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is used.
54*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0x8000, 4096, 0xff);
55*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 1; i <= kMaxCachedSize; i++) {
56*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
57*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
58*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
59*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xab), buffer) << "Failed at size " << i;
60*eb293b8fSAndroid Build Coastguard Worker   }
61*eb293b8fSAndroid Build Coastguard Worker }
62*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,no_cached_read_after_clear)63*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, no_cached_read_after_clear) {
64*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 1; i <= kMaxCachedSize; i++) {
65*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
66*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
67*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
68*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xab), buffer) << "Failed at size " << i;
69*eb293b8fSAndroid Build Coastguard Worker   }
70*eb293b8fSAndroid Build Coastguard Worker 
71*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is not used after a reset.
72*eb293b8fSAndroid Build Coastguard Worker   memory_cache_->Clear();
73*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0x8000, 4096, 0xff);
74*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 1; i <= kMaxCachedSize; i++) {
75*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
76*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
77*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
78*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xff), buffer) << "Failed at size " << i;
79*eb293b8fSAndroid Build Coastguard Worker   }
80*eb293b8fSAndroid Build Coastguard Worker }
81*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,cached_read_across_caches)82*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, cached_read_across_caches) {
83*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> expect(16, 0xab);
84*eb293b8fSAndroid Build Coastguard Worker   expect.resize(32, 0xde);
85*eb293b8fSAndroid Build Coastguard Worker 
86*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(32);
87*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0x8ff0, buffer.data(), 32));
88*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(expect, buffer);
89*eb293b8fSAndroid Build Coastguard Worker 
90*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is used.
91*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0x8000, 4096, 0xff);
92*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0x9000, 4096, 0xff);
93*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0x8ff0, buffer.data(), 32));
94*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(expect, buffer);
95*eb293b8fSAndroid Build Coastguard Worker }
96*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,no_cache_read)97*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, no_cache_read) {
98*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = kMaxCachedSize + 1; i < 2 * kMaxCachedSize; i++) {
99*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
100*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
101*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
102*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xab), buffer) << "Failed at size " << i;
103*eb293b8fSAndroid Build Coastguard Worker   }
104*eb293b8fSAndroid Build Coastguard Worker 
105*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is not used.
106*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0x8000, 4096, 0xff);
107*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = kMaxCachedSize + 1; i < 2 * kMaxCachedSize; i++) {
108*eb293b8fSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(i);
109*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(memory_cache_->ReadFully(0x8000 + i, buffer.data(), i))
110*eb293b8fSAndroid Build Coastguard Worker         << "Read failed at size " << i;
111*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(std::vector<uint8_t>(i, 0xff), buffer) << "Failed at size " << i;
112*eb293b8fSAndroid Build Coastguard Worker   }
113*eb293b8fSAndroid Build Coastguard Worker }
114*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,read_for_cache_fail)115*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, read_for_cache_fail) {
116*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(kMaxCachedSize);
117*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0xa010, buffer.data(), kMaxCachedSize));
118*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(std::vector<uint8_t>(kMaxCachedSize, 0x50), buffer);
119*eb293b8fSAndroid Build Coastguard Worker 
120*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is not used.
121*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0xa000, 3000, 0xff);
122*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0xa010, buffer.data(), kMaxCachedSize));
123*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(std::vector<uint8_t>(kMaxCachedSize, 0xff), buffer);
124*eb293b8fSAndroid Build Coastguard Worker }
125*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(MemoryCacheTest,read_for_cache_fail_cross)126*eb293b8fSAndroid Build Coastguard Worker TEST_F(MemoryCacheTest, read_for_cache_fail_cross) {
127*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> expect(16, 0xde);
128*eb293b8fSAndroid Build Coastguard Worker   expect.resize(32, 0x50);
129*eb293b8fSAndroid Build Coastguard Worker 
130*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(32);
131*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0x9ff0, buffer.data(), 32));
132*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(expect, buffer);
133*eb293b8fSAndroid Build Coastguard Worker 
134*eb293b8fSAndroid Build Coastguard Worker   // Verify the cached data is not used for the second half but for the first.
135*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0xa000, 3000, 0xff);
136*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(memory_cache_->ReadFully(0x9ff0, buffer.data(), 32));
137*eb293b8fSAndroid Build Coastguard Worker   expect.resize(16);
138*eb293b8fSAndroid Build Coastguard Worker   expect.resize(32, 0xff);
139*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(expect, buffer);
140*eb293b8fSAndroid Build Coastguard Worker }
141*eb293b8fSAndroid Build Coastguard Worker 
142*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
143