xref: /aosp_15_r20/external/perfetto/src/trace_processor/sqlite/sqlite_utils_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2020 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 "src/trace_processor/sqlite/sqlite_utils.h"
18 
19 #include <cstdint>
20 #include <limits>
21 #include <optional>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 #include "perfetto/base/logging.h"
27 #include "perfetto/trace_processor/basic_types.h"
28 #include "src/base/test/status_matchers.h"
29 #include "src/trace_processor/sqlite/scoped_db.h"
30 #include "test/gtest_and_gmock.h"
31 
32 namespace perfetto::trace_processor::sqlite::utils {
33 
34 namespace {
35 using base::gtest_matchers::IsError;
36 
37 class GetColumnsForTableTest : public ::testing::Test {
38  public:
GetColumnsForTableTest()39   GetColumnsForTableTest() {
40     sqlite3* db = nullptr;
41     PERFETTO_CHECK(sqlite3_initialize() == SQLITE_OK);
42     PERFETTO_CHECK(sqlite3_open(":memory:", &db) == SQLITE_OK);
43     db_.reset(db);
44   }
45 
PrepareValidStatement(const std::string & sql)46   void PrepareValidStatement(const std::string& sql) {
47     int size = static_cast<int>(sql.size());
48     sqlite3_stmt* stmt;
49     ASSERT_EQ(sqlite3_prepare_v2(*db_, sql.c_str(), size, &stmt, nullptr),
50               SQLITE_OK);
51     stmt_.reset(stmt);
52   }
53 
RunStatement(const std::string & sql)54   void RunStatement(const std::string& sql) {
55     PrepareValidStatement(sql);
56     ASSERT_EQ(sqlite3_step(stmt_.get()), SQLITE_DONE);
57   }
58 
59  protected:
60   ScopedDb db_;
61   ScopedStmt stmt_;
62 };
63 
TEST_F(GetColumnsForTableTest,ValidInput)64 TEST_F(GetColumnsForTableTest, ValidInput) {
65   RunStatement("CREATE TABLE foo (name STRING, ts INT, dur INT);");
66   std::vector<std::pair<SqlValue::Type, std::string>> columns;
67   ASSERT_OK(sqlite::utils::GetColumnsForTable(*db_, "foo", columns));
68 }
69 
TEST_F(GetColumnsForTableTest,UnknownType)70 TEST_F(GetColumnsForTableTest, UnknownType) {
71   // Currently GetColumnsForTable does not work with tables containing types it
72   // doesn't recognise. This just ensures that the query fails rather than
73   // crashing.
74   RunStatement("CREATE TABLE foo (name NUM, ts INT, dur INT);");
75   std::vector<std::pair<SqlValue::Type, std::string>> columns;
76   ASSERT_THAT(sqlite::utils::GetColumnsForTable(*db_, "foo", columns),
77               IsError());
78 }
79 
TEST_F(GetColumnsForTableTest,UnknownTableName)80 TEST_F(GetColumnsForTableTest, UnknownTableName) {
81   std::vector<std::pair<SqlValue::Type, std::string>> columns;
82   ASSERT_THAT(sqlite::utils::GetColumnsForTable(*db_, "unknowntable", columns),
83               IsError());
84 }
85 
TEST(SqliteUtilsTest,ExtractFromSqlValueInt32)86 TEST(SqliteUtilsTest, ExtractFromSqlValueInt32) {
87   std::optional<int32_t> int32;
88 
89   static constexpr int64_t kMin = std::numeric_limits<int32_t>::min();
90   static constexpr int64_t kMax = std::numeric_limits<int32_t>::max();
91 
92   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), int32).ok());
93   ASSERT_EQ(*int32, 1234);
94 
95   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), int32).ok());
96   ASSERT_EQ(*int32, kMin);
97 
98   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), int32).ok());
99   ASSERT_EQ(*int32, kMax);
100 
101   ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), int32).ok());
102   ASSERT_FALSE(int32.has_value());
103 
104   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(kMax + 1), int32).ok());
105   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), int32).ok());
106   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), int32).ok());
107 }
108 
TEST(SqliteUtilsTest,ExtractFromSqlValueUint32)109 TEST(SqliteUtilsTest, ExtractFromSqlValueUint32) {
110   std::optional<uint32_t> uint32;
111 
112   static constexpr int64_t kMin = std::numeric_limits<uint32_t>::min();
113   static constexpr int64_t kMax = std::numeric_limits<uint32_t>::max();
114 
115   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), uint32).ok());
116   ASSERT_EQ(*uint32, 1234u);
117 
118   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), uint32).ok());
119   ASSERT_EQ(*uint32, kMin);
120 
121   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), uint32).ok());
122   ASSERT_EQ(*uint32, kMax);
123 
124   ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), uint32).ok());
125   ASSERT_FALSE(uint32.has_value());
126 
127   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(kMax + 1), uint32).ok());
128   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), uint32).ok());
129   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), uint32).ok());
130 }
131 
TEST(SqliteUtilsTest,ExtractFromSqlValueInt64)132 TEST(SqliteUtilsTest, ExtractFromSqlValueInt64) {
133   std::optional<int64_t> int64;
134 
135   static constexpr int64_t kMin = std::numeric_limits<int64_t>::min();
136   static constexpr int64_t kMax = std::numeric_limits<int64_t>::max();
137 
138   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), int64).ok());
139   ASSERT_EQ(*int64, 1234);
140 
141   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), int64).ok());
142   ASSERT_EQ(*int64, kMin);
143 
144   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), int64).ok());
145   ASSERT_EQ(*int64, kMax);
146 
147   ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), int64).ok());
148   ASSERT_FALSE(int64.has_value());
149 
150   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), int64).ok());
151   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), int64).ok());
152 }
153 
TEST(SqliteUtilsTest,ExtractFromSqlValueDouble)154 TEST(SqliteUtilsTest, ExtractFromSqlValueDouble) {
155   std::optional<double> doub;
156 
157   static constexpr double kMin = std::numeric_limits<double>::min();
158   static constexpr double kMax = std::numeric_limits<double>::max();
159 
160   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(1234.1), doub).ok());
161   ASSERT_EQ(*doub, 1234.1);
162 
163   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(kMin), doub).ok());
164   ASSERT_EQ(*doub, kMin);
165 
166   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(kMax), doub).ok());
167   ASSERT_EQ(*doub, kMax);
168 
169   ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), doub).ok());
170   ASSERT_FALSE(doub.has_value());
171 
172   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(1234), doub).ok());
173   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), doub).ok());
174 }
175 
TEST(SqliteUtilsTest,ExtractFromSqlValueString)176 TEST(SqliteUtilsTest, ExtractFromSqlValueString) {
177   std::optional<const char*> string;
178 
179   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::String("foo"), string).ok());
180   ASSERT_STREQ(*string, "foo");
181 
182   ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), string).ok());
183   ASSERT_FALSE(string.has_value());
184 
185   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(1234), string).ok());
186   ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(123.1), string).ok());
187 }
188 
189 }  // namespace
190 }  // namespace perfetto::trace_processor::sqlite::utils
191