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 #ifndef OMIT_MULTI_VER
16 #include <gtest/gtest.h>
17
18 #include "db_constant.h"
19 #include "distributeddb_tools_unit_test.h"
20 #include "sqlite_local_kvdb_connection.h"
21 #include "sqlite_multi_ver_data_storage.h"
22 #include "sqlite_utils.h"
23
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27 using namespace std;
28
29 namespace {
30 string g_testDir;
31 string g_storeDir;
32 SQLiteMultiVerTransaction *g_transaction = nullptr;
33 const std::string CREATE_TABLE =
34 "CREATE TABLE IF NOT EXISTS version_data(key BLOB, value BLOB, oper_flag INTEGER, version INTEGER, " \
35 "timestamp INTEGER, ori_timestamp INTEGER, hash_key BLOB, " \
36 "PRIMARY key(hash_key, version));";
37 }
38
39 class DistributedDBStorageTransactionRecordTest : public testing::Test {
40 public:
41 static void SetUpTestCase(void);
42 static void TearDownTestCase(void);
43 void SetUp();
44 void TearDown();
45 };
46
SetUpTestCase(void)47 void DistributedDBStorageTransactionRecordTest::SetUpTestCase(void)
48 {
49 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
50 g_storeDir = g_testDir + "/test_multi_version.db";
51 LOGI("read directory :%s", g_storeDir.c_str());
52 }
53
TearDownTestCase(void)54 void DistributedDBStorageTransactionRecordTest::TearDownTestCase(void)
55 {
56 (void)remove(g_testDir.c_str());
57 }
58
SetUp(void)59 void DistributedDBStorageTransactionRecordTest::SetUp(void)
60 {
61 DistributedDBToolsUnitTest::PrintTestCaseInfo();
62 g_transaction = new (std::nothrow) SQLiteMultiVerTransaction();
63 ASSERT_NE(g_transaction, nullptr);
64 CipherPassword passwd;
65 int errCode = g_transaction->Initialize(g_storeDir, false, CipherType::AES_256_GCM, passwd);
66 ASSERT_EQ(errCode, E_OK);
67 }
68
TearDown(void)69 void DistributedDBStorageTransactionRecordTest::TearDown(void)
70 {
71 if (g_transaction != nullptr) {
72 delete g_transaction;
73 g_transaction = nullptr;
74 }
75
76 if (remove(g_storeDir.c_str()) != 0) {
77 LOGE("remove db failed, errno:%d", errno);
78 }
79 }
80
81 /**
82 * @tc.name: MultiverStorage001
83 * @tc.desc: test the putting non empty data with the transaction.
84 * @tc.type: FUNC
85 * @tc.require: AR000C6TRV AR000CQDTM
86 * @tc.author: wangbingquan
87 */
88 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage001, TestSize.Level1)
89 {
90 /**
91 * @tc.steps: step1. Get the current version.
92 */
93 Version originVer = 0;
94 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
95
96 Key key;
97 Value value;
98 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
99 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
100
101 /**
102 * @tc.steps: step2. Put the new data into the database.
103 * @tc.expected: step2. Put returns E_OK.
104 */
105 g_transaction->SetVersion(originVer + 1);
106 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
107
108 /**
109 * @tc.steps: step3. Get the new data and check the value.
110 * @tc.expected: step3. Get returns E_OK and the read value is equal to the put value.
111 */
112 Value valueRead;
113 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
114
115 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value), true);
116
117 /**
118 * @tc.steps: step4. Get the current max version.
119 * @tc.expected: step4. The current max version is greater than the max version before put.
120 */
121 Version currentVer = 0;
122 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
123 ASSERT_GT(currentVer, originVer);
124 }
125
126 /**
127 * @tc.name: MultiverStorage002
128 * @tc.desc: test the putting data(empty key) with the transaction.
129 * @tc.type: FUNC
130 * @tc.require: AR000C6TRV AR000CQDTM
131 * @tc.author: wangbingquan
132 */
133 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage002, TestSize.Level1)
134 {
135 /**
136 * @tc.steps: step1. Get the current version.
137 */
138 Version originVer = 0;
139 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
140
141 Key key;
142 Value value;
143 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
144 /**
145 * @tc.steps: step2. Put the new data whose key is empty and value is not empty into the database.
146 * @tc.expected: step2. Put returns not E_OK
147 */
148 g_transaction->SetVersion(originVer + 1);
149 EXPECT_NE(g_transaction->Put(key, value), E_OK);
150 /**
151 * @tc.steps: step3. Get the current max version.
152 * @tc.expected: step3. The current max version is equal to the max version before put
153 */
154 Version currentVer = 0;
155 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
156 EXPECT_EQ(currentVer, originVer);
157 }
158
159 /**
160 * @tc.name: MultiverStorage003
161 * @tc.desc: test the putting data(empty value) with the transaction.
162 * @tc.type: FUNC
163 * @tc.require: AR000C6TRV AR000CQDTM
164 * @tc.author: wangbingquan
165 */
166 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage003, TestSize.Level1)
167 {
168 /**
169 * @tc.steps: step1. Get the current version.
170 */
171 Version originVer = 0;
172 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
173
174 Key key;
175 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
176 Value value;
177 /**
178 * @tc.steps: step2. Put the new data whose key is not empty and value is empty into the database.
179 * @tc.expected: step2. Put returns E_OK
180 */
181 g_transaction->SetVersion(originVer + 1);
182 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
183
184 Value valueRead;
185 /**
186 * @tc.steps: step3. Get the new data and check the value.
187 * @tc.expected: step3. Get returns E_OK and the read value is equal to the put value.
188 */
189 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
190 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value), true);
191 /**
192 * @tc.steps: step4. Get the current max version.
193 * @tc.expected: step4. The current max version is greater than the max version before put.
194 */
195 Version currentVer = 0;
196 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
197 ASSERT_GT(currentVer, originVer);
198 }
199
200 /**
201 * @tc.name: MultiverStorage004
202 * @tc.desc: Update the data value to non-empty with the transaction.
203 * @tc.type: FUNC
204 * @tc.require: AR000C6TRV AR000CQDTM
205 * @tc.author: wangbingquan
206 */
207 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage004, TestSize.Level1)
208 {
209 /**
210 * @tc.steps: step1. Get the current version.
211 */
212 Version originVer = 0;
213 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
214
215 Key key;
216 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
217 Value value;
218 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
219
220 /**
221 * @tc.steps: step2. Put the data whose key is not empty and value is empty into the database.
222 * @tc.expected: step2. Put returns E_OK
223 */
224 g_transaction->SetVersion(originVer + 1);
225 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
226 Version currentVer = 0;
227 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
228 EXPECT_GT(currentVer, originVer);
229 originVer = currentVer;
230 g_transaction->ResetVersion();
231
232 Value valueChanged;
233
234 /**
235 * @tc.steps: step3. Update the data with another non-empty value.
236 */
237 DistributedDBToolsUnitTest::GetRandomKeyValue(valueChanged);
238 g_transaction->SetVersion(originVer + 1);
239 EXPECT_EQ(g_transaction->Put(key, valueChanged), E_OK);
240 Value valueRead;
241 /**
242 * @tc.steps: step4. Get the data according the key and check the value.
243 * @tc.steps: step5. Get the current max version.
244 * @tc.expected: step4. Get returns E_OK and the value is equal to the new put value.
245 * @tc.expected: step5. The current max version is greater than the max version before update.
246 */
247 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
248 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, valueChanged), true);
249
250 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
251 ASSERT_GT(currentVer, originVer);
252 }
253
254 /**
255 * @tc.name: MultiverStorage005
256 * @tc.desc: Update the data value to empty with the transaction.
257 * @tc.type: FUNC
258 * @tc.require: AR000C6TRV AR000CQDTM
259 * @tc.author: wangbingquan
260 */
261 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage005, TestSize.Level1)
262 {
263 /**
264 * @tc.steps: step1. Get the current version.
265 */
266 Version originVer = 0;
267 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
268
269 Key key;
270 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
271 Value value;
272 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
273 /**
274 * @tc.steps: step2. Put the data whose key is not empty and value is not empty into the database.
275 * @tc.expected: step2. Put returns E_OK
276 */
277 g_transaction->SetVersion(originVer + 1);
278 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
279 Version currentVer = 0;
280 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
281 EXPECT_GT(currentVer, originVer);
282 originVer = currentVer;
283 g_transaction->ResetVersion();
284
285 Value valueChanged;
286 /**
287 * @tc.steps: step3. Update the data with empty value.
288 */
289 g_transaction->SetVersion(originVer + 1);
290 EXPECT_EQ(g_transaction->Put(key, valueChanged), E_OK);
291 Value valueRead;
292 /**
293 * @tc.steps: step4. Get the data according the key and check the value.
294 * @tc.steps: step5. Get the current max version.
295 * @tc.expected: step4. Get returns E_OK and the value is empty.
296 * @tc.expected: step5. The current max version is greater than the max version before update.
297 */
298 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
299 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, valueChanged), true);
300 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
301 ASSERT_GT(currentVer, originVer);
302 }
303
304 /**
305 * @tc.name: MultiverStorage006
306 * @tc.desc: Delete the existed data with the transaction.
307 * @tc.type: FUNC
308 * @tc.require: AR000C6TRV AR000CQDTM
309 * @tc.author: wangbingquan
310 */
311 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage006, TestSize.Level1)
312 {
313 /**
314 * @tc.steps: step1. Get the current version.
315 */
316 Version originVer = 0;
317 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
318
319 Key key;
320 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
321 Value value;
322 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
323 /**
324 * @tc.steps: step2. Put the data whose key is not empty and value is not empty into the database.
325 * @tc.expected: step2. Put returns E_OK
326 */
327 g_transaction->SetVersion(originVer + 1);
328 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
329 Version currentVer = 0;
330 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
331 EXPECT_GT(currentVer, originVer);
332 originVer = currentVer;
333
334 EXPECT_EQ(g_transaction->Get(key, value), E_OK);
335 Value valueChanged;
336 /**
337 * @tc.steps: step3. Delete the data according the key.
338 * @tc.expected: step3. Delete returns E_OK.
339 */
340 g_transaction->SetVersion(originVer + 1);
341 EXPECT_EQ(g_transaction->Delete(key), E_OK);
342 Value valueRead;
343 /**
344 * @tc.steps: step4. Get the value according the key.
345 * @tc.expected: step4. Get returns -E_NOT_FOUND.
346 */
347 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
348 /**
349 * @tc.steps: step5. Get the current max version.
350 * @tc.expected: step5. The current max version is greater than the max version before delete.
351 */
352 currentVer = 0;
353 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
354 ASSERT_GT(currentVer, originVer);
355 }
356
357 /**
358 * @tc.name: MultiverStorage007
359 * @tc.desc: Delete the non-existed data with the transaction.
360 * @tc.type: FUNC
361 * @tc.require: AR000C6TRV AR000CQDTM
362 * @tc.author: wangbingquan
363 */
364 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage007, TestSize.Level1)
365 {
366 /**
367 * @tc.steps: step1. Get the current version.
368 */
369 Version originVer = 0;
370 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
371
372 Key key = {12, 57, 89};
373 Value value;
374 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
375 g_transaction->SetVersion(originVer + 1);
376 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
377 Version currentVer = 0;
378 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
379 EXPECT_GT(currentVer, originVer);
380 originVer = currentVer;
381 g_transaction->ResetVersion();
382
383 Key newKey = {87, 68, 78};
384 /**
385 * @tc.steps: step2. Delete the non-existed data according the key.
386 * @tc.expected: step2. Delete returns not E_OK.
387 */
388 g_transaction->SetVersion(originVer + 1);
389 EXPECT_NE(g_transaction->Delete(newKey), E_OK);
390 /**
391 * @tc.steps: step3. Get the current max version.
392 * @tc.expected: step2. The current max version is equal to the max version before delete.
393 */
394 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
395 EXPECT_EQ(currentVer, originVer);
396 }
397
398 /**
399 * @tc.name: MultiverStorage008
400 * @tc.desc: Delete an empty key with the transaction.
401 * @tc.type: FUNC
402 * @tc.require: AR000C6TRV AR000CQDTM
403 * @tc.author: wangbingquan
404 */
405 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage008, TestSize.Level1)
406 {
407 /**
408 * @tc.steps: step1. Get the current version.
409 */
410 Version originVer = 0;
411 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
412
413 Key key;
414 /**
415 * @tc.steps: step2. Delete the data whose key is empty from the empty database.
416 * @tc.steps: step3. Get the current max version.
417 * @tc.expected: step2. Delete returns not E_OK
418 * @tc.expected: step3. The current max version is equal to the max version before delete.
419 */
420 g_transaction->SetVersion(originVer + 1);
421 EXPECT_NE(g_transaction->Delete(key), E_OK);
422 Version currentVer = 0;
423 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
424 EXPECT_EQ(currentVer, originVer);
425 originVer = currentVer;
426 g_transaction->ResetVersion();
427
428 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
429 Value value;
430 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
431 /**
432 * @tc.steps: step4. Put the non-empty key and non-empty value into the database.
433 */
434 g_transaction->SetVersion(originVer + 1);
435 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
436 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
437 EXPECT_NE(currentVer, originVer);
438 originVer = currentVer;
439 g_transaction->ResetVersion();
440 key.clear();
441 /**
442 * @tc.steps: step5. Delete the data whose key is empty from the non-empty database.
443 * @tc.steps: step6. Get the current max version.
444 * @tc.expected: step5. Delete returns not E_OK
445 * @tc.expected: step6. The current max version is equal to the max version before delete.
446 */
447 g_transaction->SetVersion(originVer + 1);
448 EXPECT_NE(g_transaction->Delete(key), E_OK);
449 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
450 EXPECT_EQ(currentVer, originVer);
451 }
452
453 /**
454 * @tc.name: MultiverStorage009
455 * @tc.desc: Clear the existed data with the transaction.
456 * @tc.type: FUNC
457 * @tc.require: AR000C6TRV AR000CQDTM
458 * @tc.author: wangbingquan
459 */
460 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage009, TestSize.Level1)
461 {
462 /**
463 * @tc.steps: step1. Get the current version.
464 */
465 Version originVer = 0;
466 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, originVer), E_OK);
467 Key key1, key2;
468 Value value1, value2;
469
470 DistributedDBToolsUnitTest::GetRandomKeyValue(key1);
471 DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
472 DistributedDBToolsUnitTest::GetRandomKeyValue(key2);
473 DistributedDBToolsUnitTest::GetRandomKeyValue(value2);
474
475 /**
476 * @tc.steps: step2. Put 2 entries into the database.
477 * @tc.expected: step2. Put returns E_OK
478 */
479 g_transaction->SetVersion(originVer + 1);
480 EXPECT_EQ(g_transaction->Put(key1, value1), E_OK);
481 EXPECT_EQ(g_transaction->Put(key2, value2), E_OK);
482 Version currentVer = 0;
483 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
484 EXPECT_NE(currentVer, originVer);
485 originVer = currentVer;
486 g_transaction->ResetVersion();
487 /**
488 * @tc.steps: step3. Clear data from the database.
489 * @tc.expected: step3. Clear returns E_OK
490 */
491 g_transaction->SetVersion(originVer + 1);
492 EXPECT_EQ(g_transaction->Clear(), E_OK);
493 Value value1Read, value2Read;
494 /**
495 * @tc.steps: step4. Get the current max version.
496 * @tc.expected: step4. The current max version is greater than the max version before clear.
497 */
498 EXPECT_EQ(g_transaction->GetMaxVersion(MultiVerDataType::ALL_TYPE, currentVer), E_OK);
499 EXPECT_GT(currentVer, originVer);
500 /**
501 * @tc.steps: step5. Get the put data before clear.
502 * @tc.expected: step5. Cannot get the data after clear.
503 */
504 EXPECT_NE(g_transaction->Get(key1, value1Read), E_OK);
505 EXPECT_NE(g_transaction->Get(key2, value2Read), E_OK);
506 }
507
508 /**
509 * @tc.name: MultiverStorage010
510 * @tc.desc: Get the existed data with the transaction.
511 * @tc.type: FUNC
512 * @tc.require: AR000C6TRV AR000CQDTM
513 * @tc.author: wangbingquan
514 */
515 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage010, TestSize.Level1)
516 {
517 /**
518 * @tc.steps: step1. Generate the random data.
519 */
520 Key key;
521 Value value;
522 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
523 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
524
525 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
526 Value valueRead;
527 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
528 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value), true);
529 }
530
531 /**
532 * @tc.name: MultiverStorage011
533 * @tc.desc: Get the non-existed data with the transaction.
534 * @tc.type: FUNC
535 * @tc.require: AR000C6TRV AR000CQDTM
536 * @tc.author: wangbingquan
537 */
538 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage011, TestSize.Level1)
539 {
540 /**
541 * @tc.steps: step1. Generate the random data.
542 */
543 Key key;
544 Value value, valueRead;
545 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
546 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
547 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
548
549 /**
550 * @tc.steps: step2. Put the data whose key is not empty and value is not empty into the database.
551 * @tc.expected: step2. Put returns E_OK
552 */
553 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
554
555 key.push_back('7');
556 /**
557 * @tc.steps: step3. Get the non-existed key.
558 * @tc.expected: step3. Get returns E_OK
559 */
560 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
561 }
562
563 /**
564 * @tc.name: MultiverStorage012
565 * @tc.desc: Get the empty-key data with the transaction.
566 * @tc.type: FUNC
567 * @tc.require: AR000C6TRV AR000CQDTM
568 * @tc.author: wangbingquan
569 */
570 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage012, TestSize.Level1)
571 {
572 /**
573 * @tc.steps: step1. Generate the random data.
574 */
575 Key key;
576 Value value;
577 /**
578 * @tc.steps: step2. Get the value according the empty key from the empty database.
579 * @tc.expected: step2. Get returns not E_OK.
580 */
581 EXPECT_NE(g_transaction->Get(key, value), E_OK);
582 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
583 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
584 /**
585 * @tc.steps: step3. Put the non-empty data into the database.
586 */
587 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
588 Key keyEmpty;
589 /**
590 * @tc.steps: step4. Get the value according the empty key from the non-empty database.
591 * @tc.expected: step4. Get returns not E_OK.
592 */
593 EXPECT_NE(g_transaction->Get(keyEmpty, value), E_OK);
594 }
595
596 /**
597 * @tc.name: MultiverStorage013
598 * @tc.desc: Get the deleted data with the transaction.
599 * @tc.type: FUNC
600 * @tc.require: AR000C6TRV AR000CQDTM
601 * @tc.author: wangbingquan
602 */
603 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage013, TestSize.Level1)
604 {
605 /**
606 * @tc.steps: step1. Generate the random data.
607 */
608 Key key;
609 Value value;
610 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
611 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
612 /**
613 * @tc.steps: step2. put the non-empty data into the database.
614 */
615 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
616 EXPECT_EQ(g_transaction->Get(key, value), E_OK);
617 /**
618 * @tc.steps: step3. delete the data from the database.
619 */
620 EXPECT_EQ(g_transaction->Delete(key), E_OK);
621 Value valueRead;
622 /**
623 * @tc.steps: step4. Get the value according the key.
624 * @tc.expected: step4. Get returns -E_NOT_FOUND.
625 */
626 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
627 }
628
629 /**
630 * @tc.name: MultiverStorage014
631 * @tc.desc: Get the modified data with the transaction.
632 * @tc.type: FUNC
633 * @tc.require: AR000C6TRV AR000CQDTM
634 * @tc.author: wangbingquan
635 */
636 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage014, TestSize.Level1)
637 {
638 /**
639 * @tc.steps: step1. Generate the random data.
640 */
641 Key key;
642 Value value;
643
644 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
645 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
646 /**
647 * @tc.steps: step2. put the non-empty data into the database.
648 */
649 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
650 Value valueChanged = value;
651 valueChanged.push_back('H');
652 /**
653 * @tc.steps: step3. update the data into the database.
654 */
655 EXPECT_EQ(g_transaction->Put(key, valueChanged), E_OK);
656 Value valueRead;
657 /**
658 * @tc.steps: step4. Get the value according the key and check the value.
659 * @tc.expected: step4. Get returns E_OK and the read value is equal to the put value.
660 */
661 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
662 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, valueChanged), true);
663 }
664
665 /**
666 * @tc.name: MultiverStorage015
667 * @tc.desc: Get the data after clear with the transaction.
668 * @tc.type: FUNC
669 * @tc.require: AR000C6TRV AR000CQDTM
670 * @tc.author: wangbingquan
671 */
672 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage015, TestSize.Level1)
673 {
674 /**
675 * @tc.steps: step1. Generate the random data.
676 */
677 Key key;
678 Value value;
679
680 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
681 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
682
683 /**
684 * @tc.steps: step2. put the non-empty data into the database.
685 */
686 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
687 /**
688 * @tc.steps: step3. clear the database.
689 */
690 EXPECT_EQ(g_transaction->Clear(), E_OK);
691 Value valueRead;
692 /**
693 * @tc.steps: step4. get the data from the database after clear.
694 * @tc.expected: step4. Get returns -E_NOT_FOUND.
695 */
696 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
697 }
698
699 /**
700 * @tc.name: MultiverStorage016
701 * @tc.desc: Get the new inserted data after clear with the transaction.
702 * @tc.type: FUNC
703 * @tc.require: AR000C6TRV AR000CQDTM
704 * @tc.author: wangbingquan
705 */
706 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage016, TestSize.Level1)
707 {
708 /**
709 * @tc.steps: step1. Generate the random data.
710 */
711 Key key1;
712 Value value1;
713
714 DistributedDBToolsUnitTest::GetRandomKeyValue(key1);
715 DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
716
717 /**
718 * @tc.steps: step2. put the non-empty data into the database.
719 */
720 EXPECT_EQ(g_transaction->Put(key1, value1), E_OK);
721 /**
722 * @tc.steps: step3. clear the database.
723 */
724 EXPECT_EQ(g_transaction->Clear(), E_OK);
725 Value valueRead;
726 EXPECT_EQ(g_transaction->Get(key1, valueRead), -E_NOT_FOUND);
727 Value value2;
728 DistributedDBToolsUnitTest::GetRandomKeyValue(value2);
729 /**
730 * @tc.steps: step4. re-put the data into the database using another value.
731 */
732 EXPECT_EQ(g_transaction->Put(key1, value2), E_OK);
733 /**
734 * @tc.steps: step5. Get the value according the key and check the value.
735 * @tc.expected: step5. Get returns E_OK and the read value is equal to the new put value.
736 */
737 EXPECT_EQ(g_transaction->Get(key1, valueRead), E_OK);
738 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value2), true);
739 }
740
741 /**
742 * @tc.name: MultiverStorage017
743 * @tc.desc: Get the new inserted data after delete with the transaction.
744 * @tc.type: FUNC
745 * @tc.require: AR000C6TRV AR000CQDTM
746 * @tc.author: wangbingquan
747 */
748 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage017, TestSize.Level1)
749 {
750 /**
751 * @tc.steps: step1. Get the random data.
752 */
753 Key key;
754 Value value;
755 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
756 DistributedDBToolsUnitTest::GetRandomKeyValue(value, 79);
757
758 /**
759 * @tc.steps: step2. Put one data into the database.
760 */
761 EXPECT_EQ(g_transaction->Put(key, value), E_OK);
762 /**
763 * @tc.steps: step3. Delete the data from the database.
764 */
765 EXPECT_EQ(g_transaction->Delete(key), E_OK);
766 Value valueRead;
767 /**
768 * @tc.steps: step4. Get the data from the database according the key.
769 * @tc.expected: step4. Get returns -E_NOT_FOUND.
770 */
771 EXPECT_EQ(g_transaction->Get(key, valueRead), -E_NOT_FOUND);
772 Value valueChanged;
773 /**
774 * @tc.steps: step5. Put the same key, different value into the database.
775 */
776 DistributedDBToolsUnitTest::GetRandomKeyValue(valueChanged, 178);
777 EXPECT_EQ(g_transaction->Put(key, valueChanged), E_OK);
778 /**
779 * @tc.steps: step6. Get the data from the database according the key.
780 * @tc.expected: step6. Get returns E_OK and the get value is equal to the value put int the step5.
781 */
782 EXPECT_EQ(g_transaction->Get(key, valueRead), E_OK);
783 EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, valueChanged), true);
784 }
785
786 /**
787 * @tc.name: MultiverStorage018
788 * @tc.desc: Get the batch inserted data through the non-empty prefix key.
789 * @tc.type: FUNC
790 * @tc.require: AR000C6TRV AR000CQDTM
791 * @tc.author: wangbingquan
792 */
793 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage018, TestSize.Level1)
794 {
795 /**
796 * @tc.steps: step1. Put the batch data into the database(3 entries have the same prefix key,
797 * and another has different prefix key).
798 */
799 Entry entry1, entry2, entry3, entry4;
800 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.key, 97);
801 entry2.key = entry1.key;
802 entry2.key.push_back('W');
803 entry3.key = entry1.key;
804 entry3.key.push_back('C');
805 DistributedDBToolsUnitTest::GetRandomKeyValue(entry4.key, 67);
806
807 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.value);
808 DistributedDBToolsUnitTest::GetRandomKeyValue(entry2.value);
809 DistributedDBToolsUnitTest::GetRandomKeyValue(entry3.value);
810 DistributedDBToolsUnitTest::GetRandomKeyValue(entry4.value);
811
812 EXPECT_EQ(g_transaction->Put(entry1.key, entry1.value), E_OK);
813 EXPECT_EQ(g_transaction->Put(entry2.key, entry2.value), E_OK);
814 EXPECT_EQ(g_transaction->Put(entry3.key, entry3.value), E_OK);
815 EXPECT_EQ(g_transaction->Put(entry4.key, entry4.value), E_OK);
816 /**
817 * @tc.steps: step2. Get the batch data using the prefix key.
818 * @tc.expected: step2. GetEntries returns E_OK and the number of the result entries is E_OK.
819 */
820 std::vector<Entry> entriesRead;
821 EXPECT_EQ(g_transaction->GetEntries(entry1.key, entriesRead), E_OK);
822 EXPECT_EQ(entriesRead.size(), 3UL);
823 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry1, entriesRead), true);
824 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry2, entriesRead), true);
825 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry3, entriesRead), true);
826 }
827
828 /**
829 * @tc.name: MultiverStorage019
830 * @tc.desc: Get the non-existed data through the non-empty prefix key.
831 * @tc.type: FUNC
832 * @tc.require: AR000C6TRV AR000CQDTM
833 * @tc.author: wangbingquan
834 */
835 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage019, TestSize.Level1)
836 {
837 /**
838 * @tc.steps: step1. Put the batch data into the database.
839 */
840 Entry entry1, entry2;
841 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.key, 97);
842 DistributedDBToolsUnitTest::GetRandomKeyValue(entry2.key, 204);
843
844 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.value);
845 DistributedDBToolsUnitTest::GetRandomKeyValue(entry2.value);
846
847 EXPECT_EQ(g_transaction->Put(entry1.key, entry1.value), E_OK);
848 EXPECT_EQ(g_transaction->Put(entry2.key, entry2.value), E_OK);
849 /**
850 * @tc.steps: step2. Get the batch data from the database using the prefix key different from the data put before.
851 * @tc.expected: step2. GetEntries returns -E_NOT_FOUND.
852 */
853 std::vector<Entry> entriesRead;
854 Key key;
855 DistributedDBToolsUnitTest::GetRandomKeyValue(key, 210);
856 EXPECT_EQ(g_transaction->GetEntries(key, entriesRead), -E_NOT_FOUND);
857 }
858
859 /**
860 * @tc.name: MultiverStorage020
861 * @tc.desc: Get all the data through the empty prefix key.
862 * @tc.type: FUNC
863 * @tc.require: AR000C6TRV AR000CQDTM
864 * @tc.author: wangbingquan
865 */
866 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage020, TestSize.Level1)
867 {
868 /**
869 * @tc.steps: step1. Put the data.
870 */
871 Entry entry1, entry2, entry3;
872 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.key, 134);
873 DistributedDBToolsUnitTest::GetRandomKeyValue(entry2.key, 204);
874 DistributedDBToolsUnitTest::GetRandomKeyValue(entry3.key, 43);
875 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.value);
876 DistributedDBToolsUnitTest::GetRandomKeyValue(entry2.value);
877 DistributedDBToolsUnitTest::GetRandomKeyValue(entry3.value);
878
879 EXPECT_EQ(g_transaction->Put(entry1.key, entry1.value), E_OK);
880 EXPECT_EQ(g_transaction->Put(entry2.key, entry2.value), E_OK);
881 EXPECT_EQ(g_transaction->Put(entry3.key, entry3.value), E_OK);
882 /**
883 * @tc.steps: step2. Get the batch data from the database using the empty prefix key.
884 * @tc.expected: step2. GetEntries returns E_OK and .
885 */
886 std::vector<Entry> entriesRead;
887 Key keyEmpty;
888 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), E_OK);
889 EXPECT_EQ(entriesRead.size(), 3UL);
890 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry1, entriesRead), true);
891 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry2, entriesRead), true);
892 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry3, entriesRead), true);
893 }
894
895 /**
896 * @tc.name: MultiverStorage021
897 * @tc.desc: Get the data through the empty prefix key for multiple put the same key data.
898 * @tc.type: FUNC
899 * @tc.require: AR000C6TRV AR000CQDTM
900 * @tc.author: wangbingquan
901 */
902 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage021, TestSize.Level1)
903 {
904 /**
905 * @tc.steps: step1. Put the same key, different value for 3 times into the database.
906 */
907 Key key;
908 Value value1, value2, value3;
909 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
910
911 DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 46);
912 EXPECT_EQ(g_transaction->Put(key, value1), E_OK);
913 DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 28);
914 EXPECT_EQ(g_transaction->Put(key, value2), E_OK);
915 DistributedDBToolsUnitTest::GetRandomKeyValue(value3, 157);
916 EXPECT_EQ(g_transaction->Put(key, value3), E_OK);
917 /**
918 * @tc.steps: step2. Get the batch data from the database using the empty prefix key.
919 * @tc.expected: step2. GetEntries returns E_OK and the entries size is 1.
920 */
921 std::vector<Entry> entriesRead;
922 EXPECT_EQ(g_transaction->GetEntries(key, entriesRead), E_OK);
923 EXPECT_EQ(entriesRead.size(), 1UL);
924 Entry entry = {key, value3};
925
926 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry, entriesRead), true);
927 }
928
929 /**
930 * @tc.name: MultiverStorage022
931 * @tc.desc: Get the data through the empty prefix key for deleted data.
932 * @tc.type: FUNC
933 * @tc.require: AR000C6TRV AR000CQDTM
934 * @tc.author: wangbingquan
935 */
936 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage022, TestSize.Level1)
937 {
938 std::vector<Entry> entries;
939 Entry entry;
940 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.key);
941 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.value);
942 Entry entry1 = entry;
943 entry1.key.push_back('o');
944 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.value);
945 entries.push_back(entry);
946 entries.push_back(entry1);
947 /**
948 * @tc.steps: step1. Put the batch data.
949 */
950 EXPECT_EQ(g_transaction->PutBatch(entries), E_OK);
951 /**
952 * @tc.steps: step2. Delete the batch data.
953 */
954 EXPECT_EQ(g_transaction->Delete(entry.key), E_OK);
955 EXPECT_EQ(g_transaction->Delete(entry1.key), E_OK);
956
957 /**
958 * @tc.steps: step3. Get all the data.
959 * @tc.expected: step3. Returns -E_NOT_FOUND.
960 */
961 Key keyEmpty;
962 std::vector<Entry> entriesRead;
963 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), -E_NOT_FOUND);
964 }
965
966 /**
967 * @tc.name: MultiverStorage023
968 * @tc.desc: Get the data through the empty prefix key for updated data.
969 * @tc.type: FUNC
970 * @tc.require: AR000C6TRV AR000CQDTM
971 * @tc.author: wangbingquan
972 */
973 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage023, TestSize.Level1)
974 {
975 Key key1, key2;
976 Value value1, value2;
977 DistributedDBToolsUnitTest::GetRandomKeyValue(key1, 10);
978 key2 = key1;
979 key2.push_back('S');
980 DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 46);
981 DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 28);
982 /**
983 * @tc.steps: step1. Put the batch data.
984 */
985 EXPECT_EQ(g_transaction->Put(key1, value1), E_OK);
986 EXPECT_EQ(g_transaction->Put(key2, value2), E_OK);
987 Value value1Changed, value2Changed;
988 /**
989 * @tc.steps: step2. Update the batch data.
990 */
991 DistributedDBToolsUnitTest::GetRandomKeyValue(value1Changed, 86);
992 DistributedDBToolsUnitTest::GetRandomKeyValue(value2Changed, 149);
993 EXPECT_EQ(g_transaction->Put(key1, value1Changed), E_OK);
994 EXPECT_EQ(g_transaction->Put(key2, value2Changed), E_OK);
995 Key keyEmpty;
996 /**
997 * @tc.steps: step3. Get all the data.
998 * @tc.expected: step3. the data are equal to the updated data.
999 */
1000 std::vector<Entry> entriesRead;
1001 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), E_OK);
1002 ASSERT_EQ(entriesRead.size(), 2UL);
1003
1004 Entry entry1 = {key1, value1Changed};
1005 Entry entry2 = {key2, value2Changed};
1006 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry1, entriesRead), true);
1007 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry2, entriesRead), true);
1008 }
1009
1010 /**
1011 * @tc.name: MultiverStorage024
1012 * @tc.desc: Get the data through the empty prefix key for cleared data.
1013 * @tc.type: FUNC
1014 * @tc.require: AR000C6TRV AR000CQDTM
1015 * @tc.author: wangbingquan
1016 */
1017 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage024, TestSize.Level1)
1018 {
1019 Key key1, key2;
1020 Value value1, value2;
1021 DistributedDBToolsUnitTest::GetRandomKeyValue(key1, 10);
1022 DistributedDBToolsUnitTest::GetRandomKeyValue(key2, 20);
1023 DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
1024 DistributedDBToolsUnitTest::GetRandomKeyValue(value2);
1025 /**
1026 * @tc.steps: step1. Put the batch data.
1027 */
1028 EXPECT_EQ(g_transaction->Put(key1, value1), E_OK);
1029 EXPECT_EQ(g_transaction->Put(key2, value2), E_OK);
1030 Key keyEmpty;
1031 std::vector<Entry> entriesRead;
1032 /**
1033 * @tc.steps: step2. Get all the data.
1034 * @tc.expected: step2. the data are equal to the data put before.
1035 */
1036 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), E_OK);
1037 ASSERT_EQ(entriesRead.size(), 2UL);
1038 /**
1039 * @tc.steps: step3. Clear the data and get all the data.
1040 * @tc.expected: step3. Get returns -E_NOT_FOUND.
1041 */
1042 EXPECT_EQ(g_transaction->Clear(), E_OK);
1043 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), -E_NOT_FOUND);
1044 }
1045
1046 /**
1047 * @tc.name: MultiverStorage025
1048 * @tc.desc: Get the data through the put, delete, re-put operation.
1049 * @tc.type: FUNC
1050 * @tc.require: AR000C6TRV AR000CQDTM
1051 * @tc.author: wangbingquan
1052 */
1053 HWTEST_F(DistributedDBStorageTransactionRecordTest, MultiverStorage025, TestSize.Level1)
1054 {
1055 std::vector<Entry> entries;
1056 Entry entry;
1057 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.key);
1058 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.value);
1059 Entry entry1 = entry;
1060 entry1.key.push_back('q');
1061 DistributedDBToolsUnitTest::GetRandomKeyValue(entry1.value);
1062 entries.push_back(entry);
1063 entries.push_back(entry1);
1064 /**
1065 * @tc.steps: step1. Put the batch data.
1066 */
1067 EXPECT_EQ(g_transaction->PutBatch(entries), E_OK);
1068 /**
1069 * @tc.steps: step2. Delete the batch data.
1070 */
1071 EXPECT_EQ(g_transaction->Delete(entry.key), E_OK);
1072 EXPECT_EQ(g_transaction->Delete(entry1.key), E_OK);
1073 /**
1074 * @tc.steps: step3. Get all the data.
1075 * @tc.expected: step3. Get results -E_NOT_FOUND.
1076 */
1077 Key keyEmpty;
1078 std::vector<Entry> entriesRead;
1079 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), -E_NOT_FOUND);
1080 entry.value.push_back('q');
1081 entry1.value.push_back('s');
1082 Value valueRead, valueRead1;
1083 entriesRead.clear();
1084 /**
1085 * @tc.steps: step5. Re-put the different value into the database.
1086 */
1087 EXPECT_EQ(g_transaction->Put(entry.key, valueRead), E_OK);
1088 EXPECT_EQ(g_transaction->Put(entry1.key, valueRead1), E_OK);
1089 /**
1090 * @tc.steps: step6. Get all the data.
1091 * @tc.expected: step6. Get results E_OK and the data are equal to the inserted data after deleted operation.
1092 */
1093 EXPECT_EQ(g_transaction->GetEntries(keyEmpty, entriesRead), E_OK);
1094 ASSERT_EQ(entriesRead.size(), 2UL);
1095
1096 entry.value.clear();
1097 entry1.value.clear();
1098 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry, entriesRead), true);
1099 EXPECT_EQ(DistributedDBToolsUnitTest::IsKvEntryExist(entry1, entriesRead), true);
1100 }
1101 #endif // OMIT_MULTI_VER
1102