1 /*
2 * Copyright (C) 2024 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 #include "src/trace_processor/db/column/fake_storage.h"
17
18 #include <cstdint>
19 #include <limits>
20 #include <vector>
21
22 #include "perfetto/trace_processor/basic_types.h"
23 #include "src/trace_processor/containers/bit_vector.h"
24 #include "src/trace_processor/db/column/data_layer.h"
25 #include "src/trace_processor/db/column/types.h"
26 #include "src/trace_processor/db/column/utils.h"
27 #include "test/gtest_and_gmock.h"
28
29 namespace perfetto::trace_processor {
30
operator ==(const Range & a,const Range & b)31 inline bool operator==(const Range& a, const Range& b) {
32 return std::tie(a.start, a.end) == std::tie(b.start, b.end);
33 }
34
operator ==(const BitVector & a,const BitVector & b)35 inline bool operator==(const BitVector& a, const BitVector& b) {
36 return a.size() == b.size() && a.CountSetBits() == b.CountSetBits();
37 }
38
39 namespace column {
40 namespace {
41
42 using testing::ElementsAre;
43 using testing::IsEmpty;
44
45 using Indices = DataLayerChain::Indices;
46
TEST(FakeStorage,ValidateSearchConstraints)47 TEST(FakeStorage, ValidateSearchConstraints) {
48 {
49 // All passes
50 auto fake = FakeStorageChain::SearchAll(10);
51 EXPECT_EQ(fake->ValidateSearchConstraints(FilterOp::kEq, SqlValue()),
52 SearchValidationResult::kOk);
53 }
54 {
55 // None passes
56 auto fake = FakeStorageChain::SearchNone(10);
57 EXPECT_EQ(fake->ValidateSearchConstraints(FilterOp::kEq, SqlValue()),
58 SearchValidationResult::kOk);
59 }
60 {
61 // Index vector
62 auto fake =
63 FakeStorageChain::SearchSubset(5, std::vector<uint32_t>{1, 2, 3, 4, 5});
64 EXPECT_EQ(fake->ValidateSearchConstraints(FilterOp::kEq, SqlValue()),
65 SearchValidationResult::kOk);
66 }
67 {
68 // BitVector
69 auto fake = FakeStorageChain::SearchSubset(5, BitVector{0, 1, 0, 1, 0});
70 EXPECT_EQ(fake->ValidateSearchConstraints(FilterOp::kEq, SqlValue()),
71 SearchValidationResult::kOk);
72 }
73 {
74 // Range
75 auto fake = FakeStorageChain::SearchSubset(5, Range(1, 4));
76 EXPECT_EQ(fake->ValidateSearchConstraints(FilterOp::kEq, SqlValue()),
77 SearchValidationResult::kOk);
78 }
79 }
80
TEST(FakeStorage,SingleSearch)81 TEST(FakeStorage, SingleSearch) {
82 {
83 // All passes
84 auto fake = FakeStorageChain::SearchAll(10);
85 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 5u),
86 SingleSearchResult::kMatch);
87 }
88 {
89 // None passes
90 auto fake = FakeStorageChain::SearchNone(10);
91 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 5u),
92 SingleSearchResult::kNoMatch);
93 }
94 {
95 // Index vector
96 auto fake =
97 FakeStorageChain::SearchSubset(5, std::vector<uint32_t>{1, 2, 3, 4, 5});
98 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 0u),
99 SingleSearchResult::kNoMatch);
100 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 1u),
101 SingleSearchResult::kMatch);
102 }
103 {
104 // BitVector
105 auto fake = FakeStorageChain::SearchSubset(5, BitVector{0, 1, 0, 1, 0});
106 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 0),
107 SingleSearchResult::kNoMatch);
108 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 1u),
109 SingleSearchResult::kMatch);
110 }
111 {
112 // Range
113 auto fake = FakeStorageChain::SearchSubset(5, Range(1, 4));
114 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 0),
115 SingleSearchResult::kNoMatch);
116 EXPECT_EQ(fake->SingleSearch(FilterOp::kEq, SqlValue(), 1u),
117 SingleSearchResult::kMatch);
118 }
119 }
120
TEST(FakeStorage,Search)121 TEST(FakeStorage, Search) {
122 {
123 // All passes
124 auto fake = FakeStorageChain::SearchAll(5);
125 auto ret = fake->Search(FilterOp::kEq, SqlValue(), Range(1, 3));
126 ASSERT_THAT(utils::ToIndexVectorForTests(ret), ElementsAre(1, 2));
127 }
128 {
129 // None passes
130 auto fake = FakeStorageChain::SearchNone(5);
131 auto ret = fake->Search(FilterOp::kEq, SqlValue(), Range(1, 3));
132 ASSERT_THAT(utils::ToIndexVectorForTests(ret), ElementsAre());
133 }
134 {
135 // Index vector
136 auto fake =
137 FakeStorageChain::SearchSubset(5, std::vector<uint32_t>{1, 2, 4, 5});
138 auto ret = fake->Search(FilterOp::kEq, SqlValue(), Range(0, 3));
139 ASSERT_THAT(utils::ToIndexVectorForTests(ret), ElementsAre(1, 2));
140 }
141 {
142 // BitVector
143 auto fake = FakeStorageChain::SearchSubset(5, BitVector{0, 1, 0, 1, 0});
144 auto ret = fake->Search(FilterOp::kEq, SqlValue(), Range(1, 3));
145 ASSERT_THAT(utils::ToIndexVectorForTests(ret), ElementsAre(1));
146 }
147 {
148 // Range
149 auto fake = FakeStorageChain::SearchSubset(5, Range(2, 4));
150 auto ret = fake->Search(FilterOp::kEq, SqlValue(), Range(1, 3));
151 ASSERT_THAT(utils::ToIndexVectorForTests(ret), ElementsAre(2));
152 }
153 }
154
TEST(FakeStorage,IndexSearchValidated)155 TEST(FakeStorage, IndexSearchValidated) {
156 {
157 // All passes
158 Indices indices = Indices::CreateWithIndexPayloadForTesting(
159 {1u, 0u, 3u}, Indices::State::kNonmonotonic);
160 auto fake = FakeStorageChain::SearchAll(5);
161 fake->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
162 ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0, 1, 2));
163 }
164 {
165 // None passes
166 Indices indices = Indices::CreateWithIndexPayloadForTesting(
167 {1u, 0u, 3u}, Indices::State::kNonmonotonic);
168 auto fake = FakeStorageChain::SearchNone(5);
169 fake->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
170 EXPECT_TRUE(utils::ExtractPayloadForTesting(indices).empty());
171 }
172 {
173 // BitVector
174 Indices indices = Indices::CreateWithIndexPayloadForTesting(
175 {1u, 0u, 3u}, Indices::State::kNonmonotonic);
176 auto fake = FakeStorageChain::SearchSubset(5, BitVector{0, 1, 0, 1, 0});
177 fake->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
178 ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0, 2));
179 }
180 {
181 // Index vector
182 Indices indices = Indices::CreateWithIndexPayloadForTesting(
183 {1u, 0u, 3u}, Indices::State::kNonmonotonic);
184 auto fake =
185 FakeStorageChain::SearchSubset(5, std::vector<uint32_t>{1, 2, 3});
186 fake->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
187 ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0, 2));
188 }
189 {
190 // Range
191 Indices indices = Indices::CreateWithIndexPayloadForTesting(
192 {1u, 0u, 3u}, Indices::State::kNonmonotonic);
193 auto fake = FakeStorageChain::SearchSubset(5, Range(1, 4));
194 fake->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
195 ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0, 2));
196 }
197 }
198
199 } // namespace
200 } // namespace column
201 } // namespace perfetto::trace_processor
202