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