1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
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 * \author hongqing.hu
17 * \date Dec 2020
18 * \brief Mock mysql connector interface definition for proxima search
19 engine
20 */
21
22#pragma once
23
24#include <gmock/gmock.h>
25#include "repository/binlog/mysql_connector.h"
26
27using namespace proxima::be::repository;
28using namespace ::testing;
29
30namespace proxima {
31namespace be {
32namespace repository {
33
34/*! Mock Mysql Connector
35 */
36class MockMysqlConnector : public MysqlConnector {
37 public:
38 //! Constructor
39 MockMysqlConnector(){};
40
41 //! Destructor
42 virtual ~MockMysqlConnector() {}
43
44 //! Init Mysql Connector
45 MOCK_METHOD3(init, int(const ailego::Uri &uri, const std::string &user,
46 const std::string &password));
47
48 //! Reconnect
49 MOCK_METHOD0(reconnect, bool());
50
51 //! Get uri
52 MOCK_CONST_METHOD0(uri, const ailego::Uri &());
53
54 //! Get data
55 MOCK_CONST_METHOD0(data, const void *());
56
57 //! Execute query
58 MOCK_METHOD3(execute_query,
59 int(const std::string &sql, MysqlResultWrapperPtr *result,
60 bool sync_fetch));
61
62 //! Execute simple command
63 MOCK_METHOD3(execute_simple_command,
64 int(enum_server_command command, const unsigned char *arg,
65 size_t arg_length));
66
67 //! Client safe read
68 MOCK_METHOD1(client_safe_read, int(unsigned long *len));
69};
70using MockMysqlConnectorPtr = std::shared_ptr<MockMysqlConnector>;
71
72class MockMysqlResultWrapper : public MysqlResultWrapper {
73 public:
74 //! Constructor
75 MockMysqlResultWrapper() : MysqlResultWrapper(nullptr, nullptr) {}
76
77 //! Destructor
78 virtual ~MockMysqlResultWrapper() {
79 for (size_t i = 0; i < buffers_.size(); ++i) {
80 delete[] lengths_[i];
81 for (size_t j = 0; j < fields_num_; ++j) {
82 delete[] buffers_[i][j];
83 }
84 delete[] buffers_[i];
85 }
86 buffers_.clear();
87 }
88
89 int init() override {
90 return init_value_;
91 }
92
93 MysqlRow *next() override {
94 if (cur_idx_ < rows_.size()) {
95 MysqlRow *row = &(rows_[cur_idx_]);
96 cur_idx_++;
97 return row;
98 }
99 return nullptr;
100 }
101
102 bool has_error() override {
103 return has_error_;
104 }
105
106 void set_has_error(bool has_error) {
107 has_error_ = has_error;
108 }
109
110 uint32_t fields_num() const override {
111 return fields_num_;
112 }
113
114 uint32_t rows_num() const override {
115 return (uint32_t)rows_.size();
116 }
117
118 const FieldMetaPtr &field_meta(unsigned int i) const override {
119 return fields_[i];
120 }
121
122 void append_field_meta(const char *field_name,
123 enum_field_types field_type = MYSQL_TYPE_VAR_STRING,
124 unsigned int field_length = 0,
125 unsigned int field_decimals = 0,
126 unsigned int field_flags = 0) {
127 FieldMetaPtr meta = std::make_shared<FieldMeta>(
128 field_name, field_type, field_length, field_decimals, field_flags);
129 fields_.emplace_back(meta);
130 fields_num_ = (unsigned int)fields_.size();
131 }
132
133 void append_row_values(std::vector<std::string> &values) {
134 MYSQL_ROW row = new char *[fields_num_];
135 unsigned long *length = new unsigned long[fields_num_];
136 for (size_t i = 0; i < values.size(); ++i) {
137 row[i] = new char[values[i].size() + 1];
138 length[i] = values[i].size();
139 memcpy(row[i], values[i].data(), length[i]);
140 row[i][length[i]] = '\0';
141 }
142 MysqlRow mysql_row(fields_num_);
143 mysql_row.reset(row, length);
144 rows_.emplace_back(mysql_row);
145
146 buffers_.emplace_back(row);
147 lengths_.emplace_back(length);
148 }
149
150 void reset() {
151 cur_idx_ = 0;
152 }
153
154 private:
155 bool has_error_{false};
156 int init_value_{0};
157 size_t cur_idx_{0};
158 std::vector<MysqlRow> rows_{};
159 std::vector<MYSQL_ROW> buffers_{};
160 std::vector<unsigned long *> lengths_{};
161};
162
163using MockMysqlResultWrapperPtr = std::shared_ptr<MockMysqlResultWrapper>;
164
165} // namespace repository
166} // namespace be
167} // namespace proxima
168