xref: /aosp_15_r20/external/perfetto/src/trace_processor/perfetto_sql/parser/perfetto_sql_test_utils.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 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 #ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_PARSER_PERFETTO_SQL_TEST_UTILS_H_
18 #define SRC_TRACE_PROCESSOR_PERFETTO_SQL_PARSER_PERFETTO_SQL_TEST_UTILS_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <ostream>
23 #include <string>
24 #include <tuple>
25 
26 #include "perfetto/base/logging.h"
27 #include "perfetto/ext/base/status_or.h"
28 #include "src/trace_processor/perfetto_sql/parser/perfetto_sql_parser.h"
29 #include "src/trace_processor/sqlite/sql_source.h"
30 #include "test/gtest_and_gmock.h"
31 
32 namespace perfetto {
33 namespace trace_processor {
34 
35 inline bool operator==(const SqlSource& a, const SqlSource& b) {
36   return a.sql() == b.sql();
37 }
38 
39 inline bool operator==(const PerfettoSqlParser::SqliteSql&,
40                        const PerfettoSqlParser::SqliteSql&) {
41   return true;
42 }
43 
44 inline bool operator==(const PerfettoSqlParser::CreateFunction& a,
45                        const PerfettoSqlParser::CreateFunction& b) {
46   return std::tie(a.returns, a.is_table, a.prototype, a.replace, a.sql) ==
47          std::tie(b.returns, b.is_table, b.prototype, b.replace, b.sql);
48 }
49 
50 inline bool operator==(const PerfettoSqlParser::CreateTable& a,
51                        const PerfettoSqlParser::CreateTable& b) {
52   return std::tie(a.name, a.sql) == std::tie(b.name, b.sql);
53 }
54 
55 inline bool operator==(const PerfettoSqlParser::CreateView& a,
56                        const PerfettoSqlParser::CreateView& b) {
57   return std::tie(a.name, a.create_view_sql) ==
58          std::tie(b.name, b.create_view_sql);
59 }
60 
61 inline bool operator==(const PerfettoSqlParser::Include& a,
62                        const PerfettoSqlParser::Include& b) {
63   return std::tie(a.key) == std::tie(b.key);
64 }
65 
66 constexpr bool operator==(const PerfettoSqlParser::CreateMacro& a,
67                           const PerfettoSqlParser::CreateMacro& b) {
68   return std::tie(a.replace, a.name, a.sql, a.args) ==
69          std::tie(b.replace, b.name, b.sql, b.args);
70 }
71 
72 constexpr bool operator==(const PerfettoSqlParser::CreateIndex& a,
73                           const PerfettoSqlParser::CreateIndex& b) {
74   return std::tie(a.replace, a.name, a.table_name, a.col_names) ==
75          std::tie(b.replace, b.name, b.table_name, b.col_names);
76 }
77 
78 constexpr bool operator==(const PerfettoSqlParser::DropIndex& a,
79                           const PerfettoSqlParser::DropIndex& b) {
80   return std::tie(a.name, a.table_name) == std::tie(b.name, b.table_name);
81 }
82 
83 inline std::ostream& operator<<(std::ostream& stream, const SqlSource& sql) {
84   return stream << "SqlSource(sql=" << testing::PrintToString(sql.sql()) << ")";
85 }
86 
87 inline std::ostream& operator<<(std::ostream& stream,
88                                 const PerfettoSqlParser::Statement& line) {
89   if (std::get_if<PerfettoSqlParser::SqliteSql>(&line)) {
90     return stream << "SqliteSql()";
91   }
92   if (auto* fn = std::get_if<PerfettoSqlParser::CreateFunction>(&line)) {
93     return stream << "CreateFn(sql=" << testing::PrintToString(fn->sql)
94                   << ", prototype=" << testing::PrintToString(fn->prototype)
95                   << ", returns=" << testing::PrintToString(fn->returns)
96                   << ", is_table=" << testing::PrintToString(fn->is_table)
97                   << ", replace=" << testing::PrintToString(fn->replace) << ")";
98   }
99   if (auto* tab = std::get_if<PerfettoSqlParser::CreateTable>(&line)) {
100     return stream << "CreateTable(name=" << testing::PrintToString(tab->name)
101                   << ", sql=" << testing::PrintToString(tab->sql) << ")";
102   }
103   if (auto* tab = std::get_if<PerfettoSqlParser::CreateView>(&line)) {
104     return stream << "CreateView(name=" << testing::PrintToString(tab->name)
105                   << ", sql=" << testing::PrintToString(tab->create_view_sql)
106                   << ")";
107   }
108   if (auto* macro = std::get_if<PerfettoSqlParser::CreateMacro>(&line)) {
109     return stream << "CreateTable(name=" << testing::PrintToString(macro->name)
110                   << ", args=" << testing::PrintToString(macro->args)
111                   << ", replace=" << testing::PrintToString(macro->replace)
112                   << ", sql=" << testing::PrintToString(macro->sql) << ")";
113   }
114   PERFETTO_FATAL("Unknown type");
115 }
116 
117 template <typename T>
118 inline bool operator==(const base::StatusOr<T>& a, const base::StatusOr<T>& b) {
119   return a.status().ok() == b.ok() &&
120          a.status().message() == b.status().message() &&
121          (!a.ok() || a.value() == b.value());
122 }
123 
124 inline std::ostream& operator<<(std::ostream& stream, const base::Status& a) {
125   return stream << "base::Status(ok=" << a.ok()
126                 << ", message=" << testing::PrintToString(a.message()) << ")";
127 }
128 
129 template <typename T>
130 inline std::ostream& operator<<(std::ostream& stream,
131                                 const base::StatusOr<T>& a) {
132   std::string val = a.ok() ? testing::PrintToString(a.value()) : "";
133   return stream << "base::StatusOr(status="
134                 << testing::PrintToString(a.status()) << ", value=" << val
135                 << ")";
136 }
137 
FindSubstr(const SqlSource & source,const std::string & needle)138 inline SqlSource FindSubstr(const SqlSource& source,
139                             const std::string& needle) {
140   size_t off = source.sql().find(needle);
141   PERFETTO_CHECK(off != std::string::npos);
142   return source.Substr(static_cast<uint32_t>(off),
143                        static_cast<uint32_t>(needle.size()));
144 }
145 
146 }  // namespace trace_processor
147 }  // namespace perfetto
148 
149 #endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_PARSER_PERFETTO_SQL_TEST_UTILS_H_
150