1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 
18 #include "distributeddb_tools_unit_test.h"
19 #include "get_query_info.h"
20 #include "log_print.h"
21 
22 using namespace testing::ext;
23 using namespace DistributedDB;
24 using namespace std;
25 
26 namespace {
27     const std::string TEST_FIELD_NAME = "$.test";
28 
CheckQueryContainer(Query & query,std::list<QueryObjNode> & checkList)29     bool CheckQueryContainer(Query &query, std::list<QueryObjNode> &checkList)
30     {
31         const std::list<QueryObjNode> queryList = GetQueryInfo::GetQueryExpression(query).GetQueryExpression();
32         if (queryList.size() != checkList.size()) {
33             return false;
34         }
35         auto queryIter = queryList.begin();
36 
37         for (auto checkIter = checkList.begin(); checkIter != checkList.end(); checkIter++, queryIter++) {
38             EXPECT_EQ(checkIter->operFlag, queryIter->operFlag);
39             EXPECT_EQ(checkIter->type, queryIter->type);
40             EXPECT_EQ(checkIter->fieldName, queryIter->fieldName);
41             if (checkIter->fieldValue.size() != queryIter->fieldValue.size()) {
42                 return false;
43             }
44             for (size_t i = 0; i < checkIter->fieldValue.size(); i++) {
45                 EXPECT_EQ(memcmp(&(checkIter->fieldValue[i]), &(queryIter->fieldValue[i]), 8), 0); // only need check 8
46                 EXPECT_EQ(checkIter->fieldValue[i].stringValue, queryIter->fieldValue[i].stringValue);
47             }
48         }
49         return true;
50     }
51 
52     template<typename T>
CreateCheckList(QueryObjType operFlag,const std::string & fieldName,const T & queryValue)53     std::list<QueryObjNode> CreateCheckList(QueryObjType operFlag, const std::string &fieldName, const T &queryValue)
54     {
55         FieldValue fieldValue;
56         QueryValueType type = GetQueryValueType::GetFieldTypeAndValue(queryValue, fieldValue);
57         std::vector<FieldValue> values{fieldValue};
58         if (type == QueryValueType::VALUE_TYPE_BOOL) {
59             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_BOOL, values}};
60             return result;
61         } else if (type == QueryValueType::VALUE_TYPE_INTEGER) {
62             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_INTEGER, values}};
63             return result;
64         } else if (type == QueryValueType::VALUE_TYPE_LONG) {
65             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_LONG, values}};
66             return result;
67         } else if (type == QueryValueType::VALUE_TYPE_DOUBLE) {
68             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_DOUBLE, values}};
69             return result;
70         } else if (type == QueryValueType::VALUE_TYPE_STRING) {
71             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_STRING, values}};
72             return result;
73         } else {
74             std::list<QueryObjNode> result{{operFlag, fieldName, QueryValueType::VALUE_TYPE_INVALID, values}};
75             return result;
76         }
77     }
78 
CheckQueryCompareOper()79     void CheckQueryCompareOper()
80     {
81         Query query1 = Query::Select().NotEqualTo(TEST_FIELD_NAME, 123); // random test data
82         std::list<QueryObjNode> result = CreateCheckList(QueryObjType::NOT_EQUALTO, TEST_FIELD_NAME, 123); // random num
83         EXPECT_TRUE(CheckQueryContainer(query1, result));
84 
85         Query query2 = Query::Select().EqualTo(TEST_FIELD_NAME, true);
86         result.clear();
87         result = CreateCheckList(QueryObjType::EQUALTO, TEST_FIELD_NAME, true);
88         EXPECT_TRUE(CheckQueryContainer(query2, result));
89 
90         Query query3 = Query::Select().GreaterThan(TEST_FIELD_NAME, 0);
91         result.clear();
92         result = CreateCheckList(QueryObjType::GREATER_THAN, TEST_FIELD_NAME, 0);
93         EXPECT_TRUE(CheckQueryContainer(query3, result));
94 
95         Query query4 = Query::Select().LessThan(TEST_FIELD_NAME, INT_MAX);
96         result.clear();
97         result = CreateCheckList(QueryObjType::LESS_THAN, TEST_FIELD_NAME, INT_MAX);
98         EXPECT_TRUE(CheckQueryContainer(query4, result));
99 
100         Query query5 = Query::Select().GreaterThanOrEqualTo(TEST_FIELD_NAME, 1.56); // random test data
101         result.clear();
102         result = CreateCheckList(QueryObjType::GREATER_THAN_OR_EQUALTO, TEST_FIELD_NAME, 1.56); // random test data
103         EXPECT_TRUE(CheckQueryContainer(query5, result));
104 
105         Query query6 = Query::Select().LessThanOrEqualTo(TEST_FIELD_NAME, 100); // random test data
106         result.clear();
107         result = CreateCheckList(QueryObjType::LESS_THAN_OR_EQUALTO, TEST_FIELD_NAME, 100); // random test data
108         EXPECT_TRUE(CheckQueryContainer(query6, result));
109     }
110 }
111 
112 class DistributedDBInterfacesQueryTest : public testing::Test {
113 public:
114     static void SetUpTestCase(void);
115     static void TearDownTestCase(void);
116     void SetUp();
117     void TearDown();
118 };
119 
SetUpTestCase(void)120 void DistributedDBInterfacesQueryTest::SetUpTestCase(void)
121 {
122 }
123 
TearDownTestCase(void)124 void DistributedDBInterfacesQueryTest::TearDownTestCase(void)
125 {
126 }
127 
SetUp(void)128 void DistributedDBInterfacesQueryTest::SetUp(void)
129 {
130     DistributedDBUnitTest::DistributedDBToolsUnitTest::PrintTestCaseInfo();
131 }
132 
TearDown(void)133 void DistributedDBInterfacesQueryTest::TearDown(void)
134 {
135 }
136 
137 /**
138   * @tc.name: Query001
139   * @tc.desc: Check the legal single query operation to see if the generated container is correct
140   * @tc.type: FUNC
141   * @tc.require: AR000DR9K6
142   * @tc.author: sunpeng
143   */
144 HWTEST_F(DistributedDBInterfacesQueryTest, Query001, TestSize.Level1)
145 {
146     Query query = Query::Select();
147     Query queryCopy = query;
148     Query queryMove = std::move(query);
149 
150     CheckQueryCompareOper();
151 
152     std::string testValue = "testValue";
153     Query query7 = Query::Select().Like(TEST_FIELD_NAME, testValue);
154     std::list<QueryObjNode> result = CreateCheckList(QueryObjType::LIKE, TEST_FIELD_NAME, testValue);
155     EXPECT_TRUE(CheckQueryContainer(query7, result));
156 
157     Query query8 = Query::Select().NotLike(TEST_FIELD_NAME, "testValue");
158     result.clear();
159     result = CreateCheckList(QueryObjType::NOT_LIKE, TEST_FIELD_NAME, testValue);
160     EXPECT_TRUE(CheckQueryContainer(query8, result));
161 
162     vector<int> fieldValues{1, 1, 1};
163     Query query9 = Query::Select().In(TEST_FIELD_NAME, fieldValues);
164     FieldValue fieldValue;
165     fieldValue.integerValue = 1;
166     std::vector<FieldValue> values{fieldValue, fieldValue, fieldValue};
167     std::list<QueryObjNode> result1{{QueryObjType::IN, TEST_FIELD_NAME, QueryValueType::VALUE_TYPE_INTEGER, values}};
168     EXPECT_TRUE(CheckQueryContainer(query9, result1));
169 
170     Query query10 = Query::Select().NotIn(TEST_FIELD_NAME, fieldValues);
171     std::list<QueryObjNode> result2{{QueryObjType::NOT_IN, TEST_FIELD_NAME,
172         QueryValueType::VALUE_TYPE_INTEGER, values}};
173     EXPECT_TRUE(CheckQueryContainer(query10, result2));
174 
175     Query query11 = Query::Select().OrderBy(TEST_FIELD_NAME, false);
176     result.clear();
177     result = CreateCheckList(QueryObjType::ORDERBY, TEST_FIELD_NAME, false);
178     EXPECT_TRUE(CheckQueryContainer(query11, result));
179 
180     Query query12 = Query::Select().Limit(1, 2);
181     values.pop_back();
182     values.back().integerValue = 2;
183     std::list<QueryObjNode> result3{{QueryObjType::LIMIT, string(), QueryValueType::VALUE_TYPE_INTEGER, values}};
184     EXPECT_TRUE(CheckQueryContainer(query12, result3));
185 
186     Query query13 = Query::Select().IsNull(TEST_FIELD_NAME);
187     std::list<QueryObjNode> result4{{QueryObjType::IS_NULL, TEST_FIELD_NAME,
188         QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()}};
189     EXPECT_TRUE(CheckQueryContainer(query13, result4));
190 }
191 
192 /**
193   * @tc.name: Query002
194   * @tc.desc: Check for illegal query conditions
195   * @tc.type: FUNC
196   * @tc.require: AR000DR9K6
197   * @tc.author: sunpeng
198   */
199 HWTEST_F(DistributedDBInterfacesQueryTest, Query002, TestSize.Level1)
200 {
201     float testValue = 1.1;
202     Query query = Query::Select().NotEqualTo(".test", testValue);
203     EXPECT_FALSE(GetQueryInfo::GetQueryExpression(query).GetErrFlag());
204 
205     EXPECT_FALSE(GetQueryInfo::GetQueryExpression(Query::Select().GreaterThan(TEST_FIELD_NAME, true)).GetErrFlag());
206 
207     EXPECT_FALSE(GetQueryInfo::GetQueryExpression(Query::Select().LessThan("$.test.12test", true)).GetErrFlag());
208 }
209 
210 /**
211   * @tc.name: Query003
212   * @tc.desc: Check combination condition
213   * @tc.type: FUNC
214   * @tc.require: AR000DR9K6
215   * @tc.author: sunpeng
216   */
217 HWTEST_F(DistributedDBInterfacesQueryTest, Query003, TestSize.Level1)
218 {
219     Query query = Query::Select().EqualTo(TEST_FIELD_NAME, true).And().GreaterThan(TEST_FIELD_NAME, 1);
220     QueryExpression queryExpression = GetQueryInfo::GetQueryExpression(query);
221     EXPECT_TRUE(queryExpression.GetErrFlag());
222     EXPECT_EQ(queryExpression.GetQueryExpression().size(), 3UL);
223 
224     Query query1 = Query::Select().GreaterThan(TEST_FIELD_NAME, 1).OrderBy(TEST_FIELD_NAME);
225     QueryExpression queryExpression1 = GetQueryInfo::GetQueryExpression(query1);
226     EXPECT_TRUE(queryExpression1.GetErrFlag());
227     EXPECT_EQ(queryExpression1.GetQueryExpression().size(), 2UL);
228 }
229 
230 /**
231  * @tc.name: Query004
232  * @tc.desc: Check QueryExpression abnormal scene
233  * @tc.type: FUNC
234  * @tc.require: DTS2024073106613
235  * @tc.author: suyue
236  */
237 HWTEST_F(DistributedDBInterfacesQueryTest, Query004, TestSize.Level1)
238 {
239     /**
240      * @tc.steps: step1. call comparison func when type is VALUE_TYPE_BOOL
241      * @tc.expected: step1. flag is false.
242      */
243     QueryExpression expression;
244     const FieldValue value = {};
245     expression.GreaterThanOrEqualTo("", QueryValueType::VALUE_TYPE_BOOL, value);
246     EXPECT_FALSE(expression.GetErrFlag());
247     expression.LessThanOrEqualTo("", QueryValueType::VALUE_TYPE_BOOL, value);
248     EXPECT_FALSE(expression.GetErrFlag());
249 
250     /**
251      * @tc.steps: step2. call RangeParamCheck func with operFlag OPER_ILLEGAL
252      * @tc.expected: step2. flag is false.
253      */
254     expression.GetQueryExpression();
255     EXPECT_EQ(expression.RangeParamCheck(), -E_INVALID_ARGS);
256     EXPECT_FALSE(expression.GetErrFlag());
257     expression.Reset();
258     EXPECT_TRUE(expression.GetErrFlag());
259 
260     /**
261      * @tc.steps: step3. call From func when tables_ is empty
262      * @tc.expected: step3. -E_INVALID_ARGS.
263      */
264     EXPECT_EQ(expression.GetExpressionStatus(), E_OK);
265     const std::string tableName1;
266     expression.From(tableName1);
267     const std::string tableName2 = "test2";
268     for (size_t i = 0; i < 2; i++) { // 传入相同tableName2次
269         expression.From(tableName2);
270     }
271     EXPECT_EQ(expression.GetExpressionStatus(), -E_INVALID_ARGS);
272 
273     /**
274      * @tc.steps: step4. call From func when tables_ is not empty
275      * @tc.expected: step4. -E_NOT_SUPPORT.
276      */
277     QueryExpression expression1;
278     EXPECT_EQ(expression1.GetExpressionStatus(), E_OK);
279     const std::vector<std::string> tableNames = {tableName1, tableName2};
280     expression1.SetTables(tableNames);
281     const std::string tableName3 = "test3";
282     expression1.From(tableName3);
283     EXPECT_EQ(expression1.GetExpressionStatus(), -E_NOT_SUPPORT);
284 }