• 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 
16 #include <gtest/gtest.h>
17 
18 #include <string>
19 
20 #include "common.h"
21 #include "grd_api_manager.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25 using namespace testing::ext;
26 using namespace OHOS::NativeRdb;
27 namespace Test {
28 class RdbReadOnlyTest : public testing::Test {
29 public:
30     static void SetUpTestCase(void);
31     static void TearDownTestCase(void);
32     void SetUp();
33     void TearDown();
34 
35     static const std::string READONLY_DATABASE_NAME;
36     static const std::string READONLY_DATABASE_NAME_18; // for testcase 18
37     static const std::string READONLY_DATABASE_BAK_NAME;
38     static const std::string DATABASE_NAME;
39     static std::shared_ptr<RdbStore> readOnlyStore;
40 };
41 
42 const std::string RdbReadOnlyTest::DATABASE_NAME = RDB_TEST_PATH + "database.db";
43 const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME = RDB_TEST_PATH + "readOnly.db";
44 const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME_18 = RDB_TEST_PATH + "readOnly1.db";
45 const std::string RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME = RDB_TEST_PATH + "readOnlyBak.db";
46 std::shared_ptr<RdbStore> RdbReadOnlyTest::readOnlyStore = nullptr;
47 
48 class ReadOnlyTestOpenCallback : public RdbOpenCallback {
49 public:
50     int OnCreate(RdbStore &store) override;
51     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
52     static const std::string CREATE_TABLE_TEST;
53 };
54 
55 const std::string ReadOnlyTestOpenCallback::CREATE_TABLE_TEST =
56     "CREATE TABLE IF NOT EXISTS test "
57     "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, salary REAL, blobType BLOB)";
58 
OnCreate(RdbStore & store)59 int ReadOnlyTestOpenCallback::OnCreate(RdbStore &store)
60 {
61     return store.ExecuteSql(CREATE_TABLE_TEST);
62 }
63 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)64 int ReadOnlyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
65 {
66     return E_OK;
67 }
68 
SetUpTestCase(void)69 void RdbReadOnlyTest::SetUpTestCase(void)
70 {
71     int errCode = E_ERROR;
72     RdbHelper::DeleteRdbStore(READONLY_DATABASE_NAME);
73     RdbStoreConfig config(READONLY_DATABASE_NAME);
74     config.SetBundleName("com.example.readOnly.rdb");
75     ReadOnlyTestOpenCallback helper;
76     // user_version is 1
77     auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
78     EXPECT_NE(nullptr, store);
79     EXPECT_EQ(E_OK, errCode);
80 
81     int64_t id;
82     ValuesBucket values;
83     values.PutString("name", "zhangSan");
84     int ret = store->Insert(id, "test", values);
85     EXPECT_EQ(E_OK, ret);
86     // id is 1
87     EXPECT_EQ(1, id);
88 
89     RdbHelper::ClearCache();
90 
91     RdbStoreConfig config1(READONLY_DATABASE_NAME);
92     config1.SetBundleName("com.example.readOnly.rdb");
93     config1.SetReadOnly(true);
94     ReadOnlyTestOpenCallback helper1;
95     // user_version is 1
96     readOnlyStore = RdbHelper::GetRdbStore(config1, 1, helper1, errCode);
97     EXPECT_NE(nullptr, readOnlyStore);
98     EXPECT_EQ(E_OK, errCode);
99 }
100 
TearDownTestCase(void)101 void RdbReadOnlyTest::TearDownTestCase(void)
102 {
103     readOnlyStore = nullptr;
104     EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
105     EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_NAME));
106     EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME));
107 }
108 
SetUp()109 void RdbReadOnlyTest::SetUp()
110 {
111 }
112 
TearDown()113 void RdbReadOnlyTest::TearDown()
114 {
115 }
116 
117 /**
118  * @tc.name: RdbStore_ReadOnly_0001, open read-only database if the database is not exist
119  * @tc.desc: 1. set isReadOnly as true
120  *           2. open read-only database
121  * @tc.type: FUNC
122  */
123 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0001, TestSize.Level1)
124 {
125     int errCode = E_ERROR;
126     RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
127     config.SetReadOnly(true);
128     ReadOnlyTestOpenCallback helper;
129     // create read-only database, user_version is 1
130     auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
131     EXPECT_EQ(nullptr, store);
132     EXPECT_EQ(E_SQLITE_CANTOPEN, errCode);
133 }
134 
135 /**
136  * @tc.name: RdbStore_ReadOnly_0002, insert data
137  * @tc.desc: insert data into read-only database
138  * @tc.type: FUNC
139  */
140 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0002, TestSize.Level1)
141 {
142     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
143 
144     int64_t id;
145     ValuesBucket values;
146     values.PutString("name", "liSi");
147     int ret = store->Insert(id, "test", values);
148     EXPECT_EQ(E_NOT_SUPPORT, ret);
149 }
150 
151 /**
152  * @tc.name: RdbStore_ReadOnly_0003, update data
153  * @tc.desc: update data in read-only database
154  * @tc.type: FUNC
155  */
156 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0003, TestSize.Level1)
157 {
158     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
159 
160     int changedRows;
161     ValuesBucket values;
162     // salary is 300.5
163     values.PutDouble("salary", 300.5);
164     auto ret = store->Update(changedRows, "test", values);
165     EXPECT_EQ(E_NOT_SUPPORT, ret);
166 }
167 
168 /**
169  * @tc.name: RdbStore_ReadOnly_0004, delete data
170  * @tc.desc: delete data from read-only database
171  * @tc.type: FUNC
172  */
173 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0004, TestSize.Level1)
174 {
175     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
176 
177     int deletedRows;
178     auto ret = store->Delete(deletedRows, "test", "id = 1");
179     EXPECT_EQ(E_NOT_SUPPORT, ret);
180 }
181 
182 /**
183  * @tc.name: RdbStore_ReadOnly_0005
184  * @tc.desc: execute transaction
185  * @tc.type: FUNC
186  */
187 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0005, TestSize.Level1)
188 {
189     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
190 
191     auto ret = store->BeginTransaction();
192     EXPECT_EQ(E_NOT_SUPPORT, ret);
193 
194     ret = store->Commit();
195     EXPECT_EQ(E_NOT_SUPPORT, ret);
196 
197     ret = store->RollBack();
198     EXPECT_EQ(E_NOT_SUPPORT, ret);
199 }
200 
201 /**
202  * @tc.name: RdbStore_ReadOnly_0006
203  * @tc.desc: batch insert data
204  * @tc.type: FUNC
205  */
206 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0006, TestSize.Level1)
207 {
208     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
209 
210     int64_t number = 0;
211     std::vector<ValuesBucket> valuesBuckets;
212     ValuesBucket values;
213     values.PutString("name", "zhangSan");
214     valuesBuckets.push_back(std::move(values));
215     int error = store->BatchInsert(number, "test", valuesBuckets);
216     EXPECT_EQ(E_NOT_SUPPORT, error);
217 }
218 
219 /**
220  * @tc.name: RdbStore_ReadOnly_0007
221  * @tc.desc: get user_version by querySql
222  * @tc.type: FUNC
223  */
224 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0007, TestSize.Level1)
225 {
226     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
227 
228     auto resultSet = store->QuerySql("PRAGMA user_version");
229 
230     EXPECT_NE(nullptr, resultSet);
231     EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
232 
233     int value = 0;
234     // column index is 0
235     EXPECT_EQ(E_OK, resultSet->GetInt(0, value));
236     EXPECT_EQ(1, value);
237 
238     EXPECT_EQ(E_OK, resultSet->Close());
239 }
240 
241 /**
242  * @tc.name: RdbStore_ReadOnly_0008
243  * @tc.desc: get user_version by execute
244  * @tc.type: FUNC
245  */
246 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0008, TestSize.Level1)
247 {
248     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
249 
250     auto [ret, object] = store->Execute("PRAGMA user_version");
251     EXPECT_EQ(E_NOT_SUPPORT, ret);
252 
253     std::tie(ret, object) = store->Execute("PRAGMA user_version=2");
254     EXPECT_EQ(E_NOT_SUPPORT, ret);
255 
256     auto [code, result] = store->ExecuteExt("PRAGMA user_version=2");
257     EXPECT_EQ(E_NOT_SUPPORT, code);
258 }
259 
260 /**
261  * @tc.name: RdbStore_ReadOnly_0009
262  * @tc.desc: query data
263  * @tc.type: FUNC
264  */
265 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0009, TestSize.Level1)
266 {
267     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
268 
269     auto resultSet = store->QuerySql("SELECT * FROM test");
270 
271     int count = 0;
272     EXPECT_EQ(E_OK, resultSet->GetRowCount(count));
273     // count is 1
274     EXPECT_EQ(1, count);
275 
276     EXPECT_EQ(E_OK, resultSet->Close());
277 }
278 
279 /**
280  * @tc.name: RdbStore_ReadOnly_0010
281  * @tc.desc: get user_version by executeSql
282  * @tc.type: FUNC
283  */
284 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0010, TestSize.Level1)
285 {
286     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
287 
288     auto ret = store->ExecuteSql("PRAGMA user_version");
289     EXPECT_EQ(E_NOT_SUPPORT, ret);
290 
291     ret = store->ExecuteSql("SELECT * FROM test");
292     EXPECT_EQ(E_NOT_SUPPORT, ret);
293 }
294 
295 /**
296  * @tc.name: RdbStore_ReadOnly_0011
297  * @tc.desc: replace data
298  * @tc.type: FUNC
299  */
300 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0011, TestSize.Level1)
301 {
302     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
303 
304     int64_t id;
305     ValuesBucket values;
306     values.PutString("name", "zhangSan");
307     int ret = store->Replace(id, "test", values);
308     EXPECT_EQ(E_NOT_SUPPORT, ret);
309 }
310 
311 /**
312  * @tc.name: RdbStore_ReadOnly_0012
313  * @tc.desc: test ExecuteAndGetLong
314  * @tc.type: FUNC
315  */
316 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0012, TestSize.Level1)
317 {
318     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
319 
320     int64_t count;
321     int ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
322     EXPECT_EQ(E_OK, ret);
323 
324     ret = store->ExecuteAndGetLong(count, "PRAGMA user_version");
325     EXPECT_EQ(E_DATABASE_BUSY, ret);
326 }
327 
328 /**
329  * @tc.name: RdbStore_ReadOnly_0013
330  * @tc.desc: test ExecuteAndGetString
331  * @tc.type: FUNC
332  */
333 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0013, TestSize.Level1)
334 {
335     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
336 
337     std::string count;
338     int ret = store->ExecuteAndGetString(count, "SELECT COUNT(*) FROM test");
339     EXPECT_EQ(E_OK, ret);
340 
341     ret = store->ExecuteAndGetString(count, "PRAGMA user_version");
342     EXPECT_EQ(E_DATABASE_BUSY, ret);
343 }
344 
345 /**
346  * @tc.name: RdbStore_ReadOnly_0014
347  * @tc.desc: test ExecuteForLastInsertedRowId
348  * @tc.type: FUNC
349  */
350 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0014, TestSize.Level1)
351 {
352     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
353 
354     int64_t outValue;
355     int ret = store->ExecuteForLastInsertedRowId(outValue, "", {});
356     EXPECT_EQ(E_NOT_SUPPORT, ret);
357 }
358 
359 /**
360  * @tc.name: RdbStore_ReadOnly_0015
361  * @tc.desc: test ExecuteForChangedRowCount
362  * @tc.type: FUNC
363  */
364 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0015, TestSize.Level1)
365 {
366     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
367 
368     int64_t outValue;
369     int ret = store->ExecuteForChangedRowCount(outValue, "", {});
370     EXPECT_EQ(E_NOT_SUPPORT, ret);
371 }
372 
373 /**
374  * @tc.name: RdbStore_ReadOnly_0016
375  * @tc.desc: get user_version by GetVersion
376  * @tc.type: FUNC
377  */
378 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0016, TestSize.Level1)
379 {
380     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
381 
382     int version = -1;
383     auto ret = store->GetVersion(version);
384     EXPECT_EQ(E_OK, ret);
385     // version is 1
386     EXPECT_EQ(1, version);
387 }
388 
389 /**
390  * @tc.name: RdbStore_ReadOnly_0017
391  * @tc.desc: set user_version by SetVersion
392  * @tc.type: FUNC
393  */
394 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0017, TestSize.Level1)
395 {
396     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
397 
398     int version = 2;
399     auto ret = store->SetVersion(version);
400     EXPECT_EQ(E_NOT_SUPPORT, ret);
401 }
402 
403 /**
404  * @tc.name: RdbStore_ReadOnly_0018
405  * @tc.desc: test vector db
406  * @tc.type: FUNC
407  */
408 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0018, TestSize.Level1)
409 {
410     if (!OHOS::NativeRdb::IsUsingArkData()) {
411         return;
412     }
413     int errCode = E_ERROR;
414     RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME_18);
415     config.SetBundleName("com.example.readOnly.rdb");
416     config.SetReadOnly(true);
417     config.SetIsVector(true);
418     ReadOnlyTestOpenCallback helper;
419     // user_version is 1
420     auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
421     ASSERT_NE(nullptr, store);
422 
423     auto [ret, id] = store->BeginTrans();
424     EXPECT_EQ(E_NOT_SUPPORT, ret);
425 
426     // id is 1
427     ret = store->Commit(1);
428     EXPECT_EQ(E_NOT_SUPPORT, ret);
429 
430     // id is 1
431     ret = store->RollBack(1);
432     EXPECT_EQ(E_NOT_SUPPORT, ret);
433 
434     ValueObject obj;
435     // id is 1
436     std::tie(ret, obj) = store->Execute("PRAGMA user_version", {}, 1);
437     EXPECT_EQ(E_NOT_SUPPORT, ret);
438 }
439 
440 /**
441  * @tc.name: RdbStore_ReadOnly_0019
442  * @tc.desc: test encrypt db
443  * @tc.type: FUNC
444  */
445 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0019, TestSize.Level1)
446 {
447     int errCode = E_ERROR;
448     RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
449     config.SetBundleName("com.example.encrypt.rdb");
450     config.SetEncryptStatus(true);
451     ReadOnlyTestOpenCallback helper;
452     // user_version is 1
453     auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
454     EXPECT_NE(nullptr, store);
455 
456     RdbHelper::ClearCache();
457 
458     RdbStoreConfig config1(RdbReadOnlyTest::DATABASE_NAME);
459     config1.SetBundleName("com.example.encrypt.rdb");
460     config1.SetReadOnly(true);
461     config1.SetEncryptStatus(true);
462     // user_version is 1
463     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
464     EXPECT_NE(nullptr, store);
465 
466     EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
467 }
468 
469 /**
470  * @tc.name: RdbStore_ReadOnly_0020
471  * @tc.desc: test attach and detach
472  * @tc.type: FUNC
473  */
474 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0020, TestSize.Level1)
475 {
476     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
477 
478     RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME);
479     auto [ret, size] = store->Attach(config, RdbReadOnlyTest::DATABASE_NAME);
480     EXPECT_EQ(E_NOT_SUPPORT, ret);
481 
482     std::tie(ret, size) = store->Detach(RdbReadOnlyTest::DATABASE_NAME);
483     EXPECT_EQ(E_NOT_SUPPORT, ret);
484 }
485 
486 /**
487  * @tc.name: RdbStore_ReadOnly_0021
488  * @tc.desc: test SetDistributedTables
489  * @tc.type: FUNC
490  */
491 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0021, TestSize.Level1)
492 {
493     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
494 
495     AbsRdbPredicates predicates("test");
496     OHOS::DistributedRdb::DistributedConfig config;
497     // type is 0
498     auto ret = store->SetDistributedTables({}, 0, config);
499     EXPECT_EQ(E_NOT_SUPPORT, ret);
500 }
501 
502 /**
503  * @tc.name: RdbStore_ReadOnly_0022
504  * @tc.desc: test CleanDirtyData
505  * @tc.type: FUNC
506  */
507 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0022, TestSize.Level1)
508 {
509     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
510 
511     uint64_t cursor = 1;
512     auto ret = store->CleanDirtyData("test", cursor);
513     EXPECT_EQ(E_NOT_SUPPORT, ret);
514 }
515 
516 /**
517  * @tc.name: RdbStore_ReadOnly_0023
518  * @tc.desc: test BatchInsert
519  * @tc.type: FUNC
520  */
521 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0023, TestSize.Level1)
522 {
523     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
524 
525     ValuesBuckets rows;
526     for (int i = 0; i < 5; i++) {
527         ValuesBucket row;
528         row.Put("name", "Jim");
529         rows.Put(row);
530     }
531     auto ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_NONE);
532     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
533     ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
534     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
535     ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_ABORT);
536     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
537     ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_FAIL);
538     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
539     ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_IGNORE);
540     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
541     ret = store->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_REPLACE);
542     EXPECT_EQ(E_NOT_SUPPORT, ret.first);
543 }
544 
545 /**
546  * @tc.name: RdbStore_CreateTransaction_001
547  * @tc.desc: test Create Transaction
548  * @tc.type: FUNC
549  */
550 HWTEST_F(RdbReadOnlyTest, RdbStore_CreateTransaction_001, TestSize.Level1)
551 {
552     std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
553     auto [errCode, trans] = store->CreateTransaction(Transaction::DEFERRED);
554     EXPECT_EQ(E_NOT_SUPPORT, errCode);
555     EXPECT_EQ(trans, nullptr);
556 
557     std::tie(errCode, trans) = store->CreateTransaction(Transaction::IMMEDIATE);
558     EXPECT_EQ(E_NOT_SUPPORT, errCode);
559     EXPECT_EQ(trans, nullptr);
560 
561     std::tie(errCode, trans) = store->CreateTransaction(Transaction::EXCLUSIVE);
562     EXPECT_EQ(E_NOT_SUPPORT, errCode);
563     EXPECT_EQ(trans, nullptr);
564 }
565 }