1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "UdrDbiUnitTests.h"
23 
24 #include <U2Core/AppContext.h>
25 #include <U2Core/U2ObjectDbi.h>
26 #include <U2Core/U2OpStatusUtils.h>
27 #include <U2Core/U2SafePoints.h>
28 #include <U2Core/UdrDbi.h>
29 #include <U2Core/UdrSchemaRegistry.h>
30 
31 namespace U2 {
32 
33 namespace {
34 const UdrSchemaId TEST_SCHEMA_ID("UnitTest");
35 const UdrSchemaId TEST_SCHEMA_ID_2("UnitTest_2");
36 const UdrSchemaId TEST_SCHEMA_ID_3("UnitTest_3");
37 const U2DataType TEST_SCHEMA_TYPE_3 = 151;
38 const int INT_FIELD = 0;
39 const int DOUBLE_FIELD = 1;
40 const int STRING_FIELD = 2;
41 const int BLOB_FIELD ATTR_UNUSED = 3;
42 
43 class SchemaObject3 : public U2Object {
44 public:
SchemaObject3()45     SchemaObject3()
46         : U2Object() {
47     }
SchemaObject3(U2DataId id,const U2DbiId & dbId)48     SchemaObject3(U2DataId id, const U2DbiId &dbId)
49         : U2Object(id, dbId, 0) {
50     }
getType() const51     U2DataType getType() const {
52         return TEST_SCHEMA_TYPE_3;
53     }
54 };
55 
getData(qint64 iv,double dv,const QString & sv)56 QList<UdrValue> getData(qint64 iv, double dv, const QString &sv) {
57     QList<UdrValue> data;
58     data << iv;
59     data << dv;
60     data << sv;
61     data << UdrValue();
62     return data;
63 }
64 
writeDataSchema2(QList<QByteArray> data,U2OpStatus & os)65 UdrRecordId writeDataSchema2(QList<QByteArray> data, U2OpStatus &os) {
66     UdrDbi *dbi = UdrTestData::getUdrDbi();
67     QList<UdrValue> rec;
68     rec << QString("url") << QString("");
69     UdrRecordId id = dbi->addRecord(TEST_SCHEMA_ID_2, rec, os);
70     CHECK_OP(os, id);
71 
72     int length = 0;
73     foreach (const QByteArray &bytes, data) {
74         length += bytes.length();
75     }
76 
77     OutputStream *oStream = dbi->createOutputStream(id, 1, length, os);
78     CHECK_OP(os, id);
79 
80     foreach (const QByteArray &bytes, data) {
81         oStream->write(bytes.constData(), bytes.size(), os);
82     }
83     delete oStream;
84 
85     return id;
86 }
87 
createObjectSchema3(const QStringList & data,U2OpStatus & os)88 U2DataId createObjectSchema3(const QStringList &data, U2OpStatus &os) {
89     UdrDbi *dbi = UdrTestData::getUdrDbi();
90 
91     SchemaObject3 obj;
92     obj.dbiId = dbi->getRootDbi()->getDbiId();
93     dbi->createObject(TEST_SCHEMA_ID_3, obj, "", os);
94     CHECK_OP(os, "");
95 
96     foreach (const QString &datum, data) {
97         QList<UdrValue> rec;
98         rec << obj.id << datum;
99         dbi->addRecord(TEST_SCHEMA_ID_3, rec, os);
100         CHECK_OP(os, "");
101     }
102     return obj.id;
103 }
104 
checkWrittenDataSchema2(const UdrRecordId & id,const QByteArray & srcData,U2OpStatus & os)105 void checkWrittenDataSchema2(const UdrRecordId &id, const QByteArray &srcData, U2OpStatus &os) {
106     UdrDbi *dbi = UdrTestData::getUdrDbi();
107     QScopedPointer<InputStream> iStream(dbi->createInputStream(id, 1, os));
108     CHECK_OP(os, );
109     CHECK_EXT(srcData.size() == iStream->available(), os.setError("wrong stream size"), );
110     QByteArray dstData(iStream->available(), 0);
111     int read = iStream->read(dstData.data(), dstData.size(), os);
112     CHECK_OP(os, );
113     CHECK_EXT(read == dstData.size(), os.setError("wrong read size"), );
114     CHECK_EXT(srcData == dstData, os.setError("wrong data"), );
115 }
116 }  // namespace
117 
118 TestDbiProvider UdrTestData::dbiProvider = TestDbiProvider();
119 const QString &UdrTestData::UDR_DB_URL("udr-dbi.ugenedb");
120 UdrDbi *UdrTestData::udrDbi = nullptr;
121 U2DataId UdrTestData::id1("");
122 U2DataId UdrTestData::id2("");
123 U2DataId UdrTestData::id_2("");
124 QByteArray UdrTestData::dataSchema2("");
125 U2DataId UdrTestData::obj1Schema3("");
126 U2DataId UdrTestData::obj2Schema3("");
127 
init()128 void UdrTestData::init() {
129     initTestUdr();
130     bool ok = dbiProvider.init(UDR_DB_URL, false);
131     SAFE_POINT(ok, "dbi provider failed to initialize", );
132 
133     udrDbi = dbiProvider.getDbi()->getUdrDbi();
134     SAFE_POINT(nullptr != udrDbi, "udr database not loaded", );
135 
136     initTestData();
137 }
138 
shutdown()139 void UdrTestData::shutdown() {
140     if (udrDbi != nullptr) {
141         U2OpStatusImpl os;
142         dbiProvider.close();
143         udrDbi = nullptr;
144         SAFE_POINT_OP(os, );
145     }
146 }
147 
initTestUdr()148 void UdrTestData::initTestUdr() {
149     UdrSchemaRegistry *reg = AppContext::getUdrSchemaRegistry();
150     SAFE_POINT(nullptr != reg, "NULL reg", );
151 
152     if (nullptr != reg->getSchemaById(TEST_SCHEMA_ID)) {
153         return;
154     }
155 
156     U2OpStatusImpl os;
157     {  // init test schema
158         UdrSchema *schema = new UdrSchema(TEST_SCHEMA_ID);
159         schema->addField(UdrSchema::FieldDesc("int", UdrSchema::INTEGER, UdrSchema::INDEXED), os);
160         schema->addField(UdrSchema::FieldDesc("double", UdrSchema::DOUBLE), os);
161         schema->addField(UdrSchema::FieldDesc("string", UdrSchema::STRING), os);
162         schema->addField(UdrSchema::FieldDesc("blob", UdrSchema::BLOB), os);
163         SAFE_POINT_OP(os, );
164 
165         schema->addMultiIndex(QList<int>() << 0 << 2, os);
166         SAFE_POINT_OP(os, );
167 
168         reg->registerSchema(schema, os);
169         SAFE_POINT_OP(os, );
170     }
171     {  // init test schema 2
172         UdrSchema *schema = new UdrSchema(TEST_SCHEMA_ID_2);
173         schema->addField(UdrSchema::FieldDesc("url", UdrSchema::STRING), os);
174         schema->addField(UdrSchema::FieldDesc("data", UdrSchema::BLOB, UdrSchema::NOT_INDEXED), os);
175         SAFE_POINT_OP(os, );
176 
177         reg->registerSchema(schema, os);
178         SAFE_POINT_OP(os, );
179     }
180     {  // init test schema 3
181         UdrSchema *schema = new UdrSchema(TEST_SCHEMA_ID_3, true);
182         schema->addField(UdrSchema::FieldDesc("data", UdrSchema::STRING), os);
183         SAFE_POINT_OP(os, );
184 
185         reg->registerSchema(schema, os);
186         SAFE_POINT_OP(os, );
187     }
188 }
189 
initTestData()190 void UdrTestData::initTestData() {
191     UdrDbi *dbi = UdrTestData::getUdrDbi();
192     SAFE_POINT(nullptr != dbi, "NULL dbi", );
193 
194     U2OpStatusImpl os;
195     {  // schema 1
196         id1 = dbi->addRecord(TEST_SCHEMA_ID, getData(20, 30.0, "test str"), os).getRecordId();
197         SAFE_POINT_OP(os, );
198         id2 = dbi->addRecord(TEST_SCHEMA_ID, getData(48, 37.0, "test str 2"), os).getRecordId();
199         SAFE_POINT_OP(os, );
200     }
201 
202     {  // schema 2
203         dataSchema2 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
204                       "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
205                       "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"
206                       "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT";
207         QList<QByteArray> data;
208         data << dataSchema2;
209         id_2 = writeDataSchema2(data, os).getRecordId();
210         SAFE_POINT_OP(os, );
211     }
212 
213     {  // schema 3
214         obj1Schema3 = createObjectSchema3(QStringList("data1"), os);
215         SAFE_POINT_OP(os, );
216         obj2Schema3 = createObjectSchema3(QStringList() << "data2"
217                                                         << "data3",
218                                           os);
219         SAFE_POINT_OP(os, );
220     }
221 }
222 
getUdrDbi()223 UdrDbi *UdrTestData::getUdrDbi() {
224     if (udrDbi == nullptr) {
225         UdrTestData::init();
226     }
227     return udrDbi;
228 }
229 
IMPLEMENT_TEST(UdrDbiUnitTests,getRecord)230 IMPLEMENT_TEST(UdrDbiUnitTests, getRecord) {
231     UdrDbi *dbi = UdrTestData::getUdrDbi();
232     U2OpStatusImpl os;
233     UdrRecord record1 = dbi->getRecord(UdrRecordId(TEST_SCHEMA_ID, UdrTestData::id1), os);
234     CHECK_NO_ERROR(os);
235     CHECK_TRUE(20 == record1.getInt(INT_FIELD, os), "int field 1");
236     CHECK_TRUE(30.0 == record1.getDouble(DOUBLE_FIELD, os), "double field 1");
237     CHECK_TRUE("test str" == record1.getString(STRING_FIELD, os), "string field 1");
238     CHECK_NO_ERROR(os);
239 
240     UdrRecord record2 = dbi->getRecord(UdrRecordId(TEST_SCHEMA_ID, UdrTestData::id2), os);
241     CHECK_NO_ERROR(os);
242     CHECK_TRUE(48 == record2.getInt(INT_FIELD, os), "int field 2");
243     CHECK_TRUE(37.0 == record2.getDouble(DOUBLE_FIELD, os), "double field 2");
244     CHECK_TRUE("test str 2" == record2.getString(STRING_FIELD, os), "string field 2");
245     CHECK_NO_ERROR(os);
246 }
247 
IMPLEMENT_TEST(UdrDbiUnitTests,addRecord_1)248 IMPLEMENT_TEST(UdrDbiUnitTests, addRecord_1) {
249     U2OpStatusImpl os;
250     UdrDbi *dbi = UdrTestData::getUdrDbi();
251 
252     QList<UdrValue> data = getData(51, 102.0, "fifty one");
253 
254     UdrRecordId id = dbi->addRecord(TEST_SCHEMA_ID, data, os);
255     CHECK_NO_ERROR(os);
256 
257     UdrRecord record = dbi->getRecord(id, os);
258     CHECK_NO_ERROR(os);
259 
260     CHECK_TRUE(51 == record.getInt(INT_FIELD, os), "int field");
261     CHECK_TRUE(102.0 == record.getDouble(DOUBLE_FIELD, os), "double field");
262     CHECK_TRUE("fifty one" == record.getString(STRING_FIELD, os), "string field");
263     CHECK_NO_ERROR(os);
264 }
265 
IMPLEMENT_TEST(UdrDbiUnitTests,addRecord_2)266 IMPLEMENT_TEST(UdrDbiUnitTests, addRecord_2) {
267     U2OpStatusImpl os;
268     UdrDbi *dbi = UdrTestData::getUdrDbi();
269 
270     QList<UdrValue> data1 = getData(5, 2.0, "who? I'm");
271     QList<UdrValue> data2 = getData(42, 51.0, "UGENE is the best");
272 
273     UdrRecordId id1 = dbi->addRecord(TEST_SCHEMA_ID, data1, os);
274     CHECK_NO_ERROR(os);
275     UdrRecordId id2 = dbi->addRecord(TEST_SCHEMA_ID, data2, os);
276     CHECK_NO_ERROR(os);
277 
278     UdrRecord record1 = dbi->getRecord(id1, os);
279     CHECK_NO_ERROR(os);
280     CHECK_TRUE(5 == record1.getInt(INT_FIELD, os), "int field 1");
281     CHECK_TRUE(2.0 == record1.getDouble(DOUBLE_FIELD, os), "double field 1");
282     CHECK_TRUE("who? I'm" == record1.getString(STRING_FIELD, os), "string field 1");
283     CHECK_NO_ERROR(os);
284 
285     UdrRecord record2 = dbi->getRecord(id2, os);
286     CHECK_NO_ERROR(os);
287     CHECK_TRUE(42 == record2.getInt(INT_FIELD, os), "int field 2");
288     CHECK_TRUE(51.0 == record2.getDouble(DOUBLE_FIELD, os), "double field 2");
289     CHECK_TRUE("UGENE is the best" == record2.getString(STRING_FIELD, os), "string field 2");
290     CHECK_NO_ERROR(os);
291 }
292 
IMPLEMENT_TEST(UdrDbiUnitTests,addRecord_with_adapter)293 IMPLEMENT_TEST(UdrDbiUnitTests, addRecord_with_adapter) {
294     U2OpStatusImpl os;
295     UdrDbi *dbi = UdrTestData::getUdrDbi();
296 
297     QList<UdrValue> data;
298     data << QString("url") << QString("");
299 
300     UdrRecordId id = dbi->addRecord(TEST_SCHEMA_ID_2, data, os);
301     CHECK_NO_ERROR(os);
302     UdrRecord record = dbi->getRecord(id, os);
303     CHECK_NO_ERROR(os);
304     CHECK_TRUE("url" == record.getString(0, os), "url field");
305     CHECK_NO_ERROR(os);
306 }
307 
IMPLEMENT_TEST(UdrDbiUnitTests,removeRecord)308 IMPLEMENT_TEST(UdrDbiUnitTests, removeRecord) {
309     U2OpStatusImpl os;
310     UdrDbi *dbi = UdrTestData::getUdrDbi();
311 
312     UdrRecordId id = dbi->addRecord(TEST_SCHEMA_ID, getData(1, 2, "three"), os);
313     CHECK_NO_ERROR(os);
314 
315     dbi->getRecord(id, os);
316     CHECK_NO_ERROR(os);
317 
318     dbi->removeRecord(id, os);
319     CHECK_NO_ERROR(os);
320 
321     dbi->getRecord(id, os);
322     CHECK_TRUE(os.hasError(), "no error");
323 }
324 
IMPLEMENT_TEST(UdrDbiUnitTests,OutputStream_write)325 IMPLEMENT_TEST(UdrDbiUnitTests, OutputStream_write) {
326     U2OpStatusImpl os;
327 
328     QByteArray bytes("test data");
329     QList<QByteArray> data;
330     data << bytes;
331     UdrRecordId id = writeDataSchema2(data, os);
332     CHECK_NO_ERROR(os);
333 
334     checkWrittenDataSchema2(id, bytes, os);
335     CHECK_NO_ERROR(os);
336 }
337 
IMPLEMENT_TEST(UdrDbiUnitTests,OutputStream_write_2)338 IMPLEMENT_TEST(UdrDbiUnitTests, OutputStream_write_2) {
339     U2OpStatusImpl os;
340 
341     QByteArray bytes1("test1");
342     QByteArray bytes2("test2");
343     QList<QByteArray> data;
344     data << bytes1 << bytes2;
345     UdrRecordId id = writeDataSchema2(data, os);
346     CHECK_NO_ERROR(os);
347 
348     checkWrittenDataSchema2(id, bytes1 + bytes2, os);
349     CHECK_NO_ERROR(os);
350 }
351 
IMPLEMENT_TEST(UdrDbiUnitTests,InputStream_read)352 IMPLEMENT_TEST(UdrDbiUnitTests, InputStream_read) {
353     U2OpStatusImpl os;
354     UdrDbi *dbi = UdrTestData::getUdrDbi();
355 
356     QScopedPointer<InputStream> iStream(dbi->createInputStream(UdrRecordId(TEST_SCHEMA_ID_2, UdrTestData::id_2), 1, os));
357     CHECK_NO_ERROR(os);
358 
359     QByteArray dstData;
360     int read = 0;
361     do {
362         QByteArray data(23, 0);
363         read = iStream->read(data.data(), data.size(), os);
364         CHECK_NO_ERROR(os);
365         if (read > 0) {
366             dstData.append(data.constData(), read);
367         }
368     } while (-1 != read);
369     CHECK_TRUE(UdrTestData::dataSchema2 == dstData, "wrong data");
370 }
371 
IMPLEMENT_TEST(UdrDbiUnitTests,InputStream_skip_OutOfRange_1)372 IMPLEMENT_TEST(UdrDbiUnitTests, InputStream_skip_OutOfRange_1) {
373     U2OpStatusImpl os;
374     UdrDbi *dbi = UdrTestData::getUdrDbi();
375 
376     QScopedPointer<InputStream> iStream(dbi->createInputStream(UdrRecordId(TEST_SCHEMA_ID_2, UdrTestData::id_2), 1, os));
377     CHECK_NO_ERROR(os);
378 
379     qint64 skipped = iStream->skip(UdrTestData::dataSchema2.size() + 1, os);
380     CHECK_NO_ERROR(os);
381     CHECK_TRUE(UdrTestData::dataSchema2.size() == skipped, "wrong skipped");
382 
383     QByteArray data(200, 0);
384     int read = iStream->read(data.data(), data.size(), os);
385     CHECK_NO_ERROR(os);
386     CHECK_TRUE(-1 == read, "wrong read");
387 }
388 
IMPLEMENT_TEST(UdrDbiUnitTests,InputStream_skip_OutOfRange_2_negative)389 IMPLEMENT_TEST(UdrDbiUnitTests, InputStream_skip_OutOfRange_2_negative) {
390     U2OpStatusImpl os;
391     UdrDbi *dbi = UdrTestData::getUdrDbi();
392 
393     QScopedPointer<InputStream> iStream(dbi->createInputStream(UdrRecordId(TEST_SCHEMA_ID_2, UdrTestData::id_2), 1, os));
394     CHECK_NO_ERROR(os);
395 
396     qint64 skipped = iStream->skip(100, os);
397     CHECK_NO_ERROR(os);
398     CHECK_TRUE(100 == skipped, "wrong skipped 1");
399 
400     skipped = iStream->skip(-200, os);
401     CHECK_NO_ERROR(os);
402     CHECK_TRUE(-100 == skipped, "wrong skipped 2");
403 
404     QByteArray data(UdrTestData::dataSchema2.size(), 0);
405     int read = iStream->read(data.data(), data.size(), os);
406     CHECK_NO_ERROR(os);
407     CHECK_TRUE(200 == read, "wrong read");
408 
409     CHECK_TRUE(UdrTestData::dataSchema2 == data, "wrong data");
410 }
411 
IMPLEMENT_TEST(UdrDbiUnitTests,InputStream_skip_Range_1)412 IMPLEMENT_TEST(UdrDbiUnitTests, InputStream_skip_Range_1) {
413     U2OpStatusImpl os;
414     UdrDbi *dbi = UdrTestData::getUdrDbi();
415 
416     QScopedPointer<InputStream> iStream(dbi->createInputStream(UdrRecordId(TEST_SCHEMA_ID_2, UdrTestData::id_2), 1, os));
417     CHECK_NO_ERROR(os);
418 
419     qint64 skipped = iStream->skip(50, os);
420     CHECK_NO_ERROR(os);
421     CHECK_TRUE(50 == skipped, "wrong skipped");
422 
423     QByteArray data(200, 0);
424     int read = iStream->read(data.data(), data.size(), os);
425     CHECK_NO_ERROR(os);
426     CHECK_TRUE(150 == read, "wrong read");
427 
428     CHECK_TRUE(UdrTestData::dataSchema2.mid(50) == data.left(read), "wrong data");
429 }
430 
IMPLEMENT_TEST(UdrDbiUnitTests,InputStream_skip_Range_2_negative)431 IMPLEMENT_TEST(UdrDbiUnitTests, InputStream_skip_Range_2_negative) {
432     U2OpStatusImpl os;
433     UdrDbi *dbi = UdrTestData::getUdrDbi();
434 
435     QScopedPointer<InputStream> iStream(dbi->createInputStream(UdrRecordId(TEST_SCHEMA_ID_2, UdrTestData::id_2), 1, os));
436     CHECK_NO_ERROR(os);
437 
438     QByteArray data(200, 0);
439     int read = iStream->read(data.data(), data.size(), os);
440     CHECK_NO_ERROR(os);
441     CHECK_TRUE(200 == read, "wrong read 1");
442     CHECK_TRUE(UdrTestData::dataSchema2 == data, "wrong data 1");
443 
444     qint64 skipped = iStream->skip(-100, os);
445     CHECK_NO_ERROR(os);
446     CHECK_TRUE(-100 == skipped, "wrong skipped");
447 
448     read = iStream->read(data.data(), data.size(), os);
449     CHECK_NO_ERROR(os);
450     CHECK_TRUE(100 == read, "wrong read 2");
451     CHECK_TRUE(UdrTestData::dataSchema2.mid(100) == data.left(read), "wrong data 2");
452 }
453 
IMPLEMENT_TEST(UdrDbiUnitTests,createObject)454 IMPLEMENT_TEST(UdrDbiUnitTests, createObject) {
455     U2OpStatusImpl os;
456     createObjectSchema3(QStringList(), os);
457     CHECK_NO_ERROR(os);
458 }
459 
IMPLEMENT_TEST(UdrDbiUnitTests,createObject_removeObject)460 IMPLEMENT_TEST(UdrDbiUnitTests, createObject_removeObject) {
461     U2OpStatusImpl os;
462     QStringList data;
463     data << "1"
464          << "2";
465     U2DataId objId = createObjectSchema3(data, os);
466     CHECK_NO_ERROR(os);
467 
468     UdrDbi *dbi = UdrTestData::getUdrDbi();
469     QList<UdrRecord> records1 = dbi->getObjectRecords(TEST_SCHEMA_ID_3, objId, os);
470     CHECK_NO_ERROR(os);
471     CHECK_TRUE(2 == records1.size(), "size 1");
472 
473     U2ObjectDbi *oDbi = dbi->getRootDbi()->getObjectDbi();
474     oDbi->removeObject(objId, os);
475     CHECK_NO_ERROR(os);
476 
477     QList<UdrRecord> records2 = dbi->getObjectRecords(TEST_SCHEMA_ID_3, objId, os);
478     CHECK_NO_ERROR(os);
479     CHECK_TRUE(0 == records2.size(), "size 1");
480 }
481 
IMPLEMENT_TEST(UdrDbiUnitTests,getObjectRecords_1)482 IMPLEMENT_TEST(UdrDbiUnitTests, getObjectRecords_1) {
483     U2OpStatusImpl os;
484     UdrDbi *dbi = UdrTestData::getUdrDbi();
485 
486     QList<UdrRecord> records = dbi->getObjectRecords(TEST_SCHEMA_ID_3, UdrTestData::obj1Schema3, os);
487     CHECK_NO_ERROR(os);
488     CHECK_TRUE(1 == records.size(), "size");
489     UdrRecord r = records.first();
490     CHECK_TRUE(r.getDataId(0, os) == UdrTestData::obj1Schema3, "object");
491     CHECK_TRUE(r.getString(1, os) == "data1", "data");
492 }
493 
IMPLEMENT_TEST(UdrDbiUnitTests,getObjectRecords_2)494 IMPLEMENT_TEST(UdrDbiUnitTests, getObjectRecords_2) {
495     U2OpStatusImpl os;
496     UdrDbi *dbi = UdrTestData::getUdrDbi();
497 
498     QList<UdrRecord> records = dbi->getObjectRecords(TEST_SCHEMA_ID_3, UdrTestData::obj2Schema3, os);
499     CHECK_NO_ERROR(os);
500     CHECK_TRUE(2 == records.size(), "size");
501 
502     UdrRecord r1 = records.first();
503     CHECK_TRUE(r1.getDataId(0, os) == UdrTestData::obj2Schema3, "object 1");
504     CHECK_TRUE(r1.getString(1, os) == "data2", "data 1");
505 
506     UdrRecord r2 = records.last();
507     CHECK_TRUE(r2.getDataId(0, os) == UdrTestData::obj2Schema3, "object 2");
508     CHECK_TRUE(r2.getString(1, os) == "data3", "data 2");
509 }
510 
511 }  // namespace U2
512