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