• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "distributed_crud_transaction_tools.h"
16 #include <gtest/gtest.h>
17 #include <dirent.h>
18 #include <string>
19 #include <sys/stat.h>
20 #include <random>
21 #include <algorithm>
22 #include <thread>
23 #include <cstdio>
24 #include <chrono>
25 #include <cmath>
26 
27 #include "distributed_test_tools.h"
28 #include "distributeddb_data_generator.h"
29 #include "kv_store_delegate.h"
30 #include "kv_store_delegate_manager.h"
31 
32 using namespace std;
33 using namespace chrono;
34 using namespace std::placeholders;
35 using namespace DistributedDB;
36 using namespace DistributedDBDataGenerator;
37 
DistributedCrudTransactionTools(KvStoreDelegate & delegate,CrudMode first,CrudMode second,bool preset,bool isLocal)38 DistributedCrudTransactionTools::DistributedCrudTransactionTools(KvStoreDelegate &delegate,
39     CrudMode first, CrudMode second, bool preset, bool isLocal)
40 {
41     this->storeDelegate_ = &delegate,
42     this->firstMode_ = first;
43     this->secondMode_ = second;
44     this->needPresetData_ = preset;
45     this->isLocal_ = isLocal;
46 }
47 
PresetValue()48 bool DistributedCrudTransactionTools::PresetValue()
49 {
50     vector<Entry> entriesBatch;
51     vector<Key> allKeys;
52     GenerateRecords(this->presetCount_, DEFAULT_START, allKeys, entriesBatch);
53 
54     for (unsigned long i = 0; i < this->presetCount_; ++i) {
55         entriesBatch[i].value = GetValueWithInt(this->presetValue_);
56     }
57     DBStatus status = DistributedTestTools::PutBatch(*storeDelegate_, entriesBatch);
58     if (status != DistributedDB::OK) {
59         MST_LOG("PresetValue failed, status %d", status);
60         return false;
61     }
62     return true;
63 }
64 
CheckFirst()65 bool DistributedCrudTransactionTools::CheckFirst()
66 {
67     vector<Entry> values = DistributedTestTools::GetEntries(*storeDelegate_, KEY_SEARCH_4);
68     if (firstMode_ == CrudMode::PUT_BATCH) {
69         MST_LOG("[CHECK LOG]putbatch first %zu", values.size());
70         if (needPresetData_) {
71             if (values.size() != 0) {
72                 return GetIntValue(values[0].value) == presetValue_;
73             } else {
74                 return true;
75             }
76         } else {
77             return (values.size() == NO_RECORD) || (values.size() == presetCount_);
78         }
79     }
80     if (firstMode_ == CrudMode::UPDATE_BATCH) {
81         if (values.size() != presetCount_) {
82             return false;
83         }
84         for (unsigned long index = 0; index < values.size(); ++index) {
85             if (GetIntValue(values[index].value) != presetValue_) {
86                 return false;
87             }
88         }
89         return true;
90     }
91     if (firstMode_ == CrudMode::DELETE_BATCH || firstMode_ == CrudMode::CLEAR) {
92         MST_LOG("[CHECK LOG]check clear first %zu", values.size());
93         if ((values.size() > NO_RECORD) && (values.size() < presetCount_)) {
94             return false;
95         }
96         return (values.size() == NO_RECORD) ||
97             ((values.size() == presetCount_ && GetIntValue(values[0].value) == presetValue_));
98     }
99     return false;
100 }
101 
CheckSecond()102 bool DistributedCrudTransactionTools::CheckSecond()
103 {
104     if (secondMode_ == CrudMode::PUT) {
105         vector<Entry> values = DistributedTestTools::GetEntries(*storeDelegate_, KEY_SEARCH_4);
106         return values.size() == NO_RECORD || GetIntValue(values[0].value) == SMALL_VALUE_SIZE ||
107             GetIntValue(values[0].value) == presetValue_;
108     }
109     if (secondMode_ == CrudMode::DELETE) {
110         Key key0 = { 'k', '0' };
111         Value value = DistributedTestTools::Get(*storeDelegate_, key0);
112         return value.size() == NO_RECORD || GetIntValue(value) == presetValue_;
113     }
114     if (secondMode_ == CrudMode::PUT_BATCH) {
115         vector<Entry> values = DistributedTestTools::GetEntries(*storeDelegate_, KEY_SEARCH_4);
116         if ((values.size() != NO_RECORD) && (values.size() != presetCount_)) {
117             return false;
118         }
119         for (unsigned long index = 0; index < values.size(); ++index) {
120             if (GetIntValue(values[0].value) != presetValue_) {
121                 return false;
122             }
123         }
124         return true;
125     }
126     if (secondMode_ == CrudMode::DELETE_BATCH || secondMode_ == CrudMode::CLEAR) {
127         vector<Entry> values = DistributedTestTools::GetEntries(*storeDelegate_, KEY_SEARCH_4);
128         if ((values.size() != NO_RECORD) && (values.size() != presetCount_)) {
129             return false;
130         }
131         for (unsigned long index = 0; index < values.size(); ++index) {
132             if (GetIntValue(values[0].value) != presetValue_) {
133                 return false;
134             }
135         }
136         return true;
137     }
138     return false;
139 }
140 
Check()141 void DistributedCrudTransactionTools::Check()
142 {
143     while (!secondComplete_) {
144         if (!firstComplete_) {
145             bool result = CheckFirst();
146             if (!result) {
147                 MST_LOG("[CHECK LOG]check first failed;%d", success_);
148             }
149             MST_LOG("[CHECK LOG]firstComplete_ failed %d;", success_);
150             success_ = result;
151         } else if (firstComplete_ && !secondComplete_) {
152             bool result = CheckSecond();
153             if (!result) {
154                 MST_LOG("[CHECK LOG]check second failed;%d", success_);
155             }
156             MST_LOG("[CHECK LOG]secondComplete_ failed %d;", success_);
157             success_ = result;
158         }
159     }
160 }
161 
Action1(KvStoreDelegate & delegate)162 bool DistributedCrudTransactionTools::Action1(KvStoreDelegate &delegate)
163 {
164     MST_LOG("firstmode %d", static_cast<int>(firstMode_));
165     if (firstMode_ == CrudMode::PUT_BATCH) {
166         return DBStatus::OK == delegate.PutBatch(entriesBatch_);
167     } else if (firstMode_ == CrudMode::DELETE_BATCH) {
168         return DBStatus::OK == delegate.DeleteBatch(allKeys_) ||
169             DBStatus::NOT_FOUND == delegate.DeleteBatch(allKeys_);
170     } else if (firstMode_ == CrudMode::CLEAR) {
171         return DBStatus::OK == delegate.Clear();
172     } else {
173         MST_LOG("unknown first %d", static_cast<int>(firstMode_));
174         return false;
175     }
176 }
177 
Action2(KvStoreDelegate & delegate)178 bool DistributedCrudTransactionTools::Action2(KvStoreDelegate &delegate)
179 {
180     MST_LOG("secondmode %d", static_cast<int>(secondMode_));
181     if (secondMode_ == CrudMode::PUT) {
182         entriesBatch_[0].value = GetValueWithInt(SMALL_VALUE_SIZE);
183         return DBStatus::OK == delegate.Put(entriesBatch_[0].key, entriesBatch_[0].value);
184     } else if (secondMode_ == CrudMode::DELETE) {
185         return DBStatus::OK == delegate.Delete(entriesBatch_[0].key) ||
186             DBStatus::NOT_FOUND == delegate.DeleteBatch(allKeys_);
187     } else if (secondMode_ == CrudMode::CLEAR) {
188         return DBStatus::OK == delegate.Clear();
189     } else if (secondMode_ == CrudMode::PUT_BATCH) {
190         return DBStatus::OK == delegate.PutBatch(entriesBatch_);
191     } else {
192         MST_LOG("unknown secondmode %d", static_cast<int>(secondMode_));
193         return false;
194     }
195 }
196 
SleepOneSecond()197 void SleepOneSecond()
198 {
199     std::this_thread::sleep_for(std::chrono::duration<int>(1));
200 }
201 
DeleteDataBase(bool success_,KvStoreDelegate * & delegate1,KvStoreDelegate * & delegate2,KvStoreDelegateManager * & delegateManager1,KvStoreDelegateManager * & delegateManager2)202 bool DeleteDataBase(bool success_, KvStoreDelegate *&delegate1, KvStoreDelegate *&delegate2,
203     KvStoreDelegateManager *&delegateManager1, KvStoreDelegateManager *&delegateManager2)
204 {
205     SleepOneSecond();
206     if ((delegateManager1->CloseKvStore(delegate1) != OK) ||
207         (delegateManager2->CloseKvStore(delegate2) != OK)) {
208         MST_LOG("closed failed!");
209     }
210     delegate1 = nullptr;
211     delegate2 = nullptr;
212     delete delegateManager1;
213     delegateManager1 = nullptr;
214     delete delegateManager2;
215     delegateManager2 = nullptr;
216     MST_LOG("[CHECK LOG]check result %d", success_);
217     return success_;
218 }
219 
testCrudTransaction()220 bool DistributedCrudTransactionTools::testCrudTransaction()
221 {
222     if (storeDelegate_ == nullptr) {
223         return false;
224     }
225 
226     DistributedTestTools::Clear(*storeDelegate_);
227     if (this->needPresetData_) {
228         if (!PresetValue()) {
229             return false;
230         }
231     }
232     GenerateRecords(this->presetCount_, DEFAULT_START, allKeys_, entriesBatch_);
233     for (unsigned long i = 0; i < this->presetCount_; ++i) {
234         entriesBatch_[i].value = GetValueWithInt(this->presetValue_);
235     }
236 
237     KvStoreDelegate *delegate1 = nullptr;
238     KvStoreDelegateManager *delegateManager1 = nullptr;
239     delegate1 = DistributedTestTools::GetDelegateSuccess(delegateManager1,
240         g_kvdbParameter1, g_kvOption);
241     if (delegateManager1 == nullptr || delegate1 == nullptr) {
242         MST_LOG("[testCrudTransaction] delegateManager1 or delegate1 is nullptr");
243         return false;
244     }
245 
246     KvStoreDelegate *delegate2 = nullptr;
247     KvStoreDelegateManager *delegateManager2 = nullptr;
248     delegate2 = DistributedTestTools::GetDelegateSuccess(delegateManager2,
249         g_kvdbParameter1, g_kvOption);
250     if (delegateManager2 == nullptr || delegate2 == nullptr) {
251         MST_LOG("[testCrudTransaction] delegateManager2 or delegate2 is nullptr");
252         return false;
253     }
254 
255     std::thread th(&DistributedCrudTransactionTools::Check, this);
256     th.detach();
257 
258     if (!Action1(*delegate1)) {
259         MST_LOG("action1 failed");
260         goto ERROR;
261     }
262     firstComplete_ = true;
263     MST_LOG("firstComplete_");
264 
265     if (!Action2(*delegate2)) {
266         MST_LOG("action2 failed");
267         goto ERROR;
268     }
269     secondComplete_ = true;
270     return DeleteDataBase(success_, delegate1, delegate2, delegateManager1, delegateManager2);
271 ERROR:
272     secondComplete_ = true;
273     return false;
274 }