* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fcntl.h>
#include <gtest/gtest.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <string>
#include "rdb_errno.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "rdb_platform.h"
#include "sqlite_utils.h"
using namespace testing::ext;
using namespace OHOS::NativeRdb;
static std::shared_ptr<RdbStore> rdbStore;
class RdbInterfaceStoreDistributedTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown()
{
}
void InsertValue(std::shared_ptr<RdbStore> &store);
void CheckResultSet(std::shared_ptr<RdbStore> &store);
static constexpr int ddmsGroupId_ = 1000;
static const std::string DRDB_NAME;
static const std::string DRDB_PATH;
};
const std::string RdbInterfaceStoreDistributedTest::DRDB_NAME = "distributed_rdb.db";
const std::string RdbInterfaceStoreDistributedTest::DRDB_PATH = "/data/test/";
class TestOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &store) override
{
std::string sql = "CREATE TABLE IF NOT EXISTS employee ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"name TEXT NOT NULL,"
"age INTEGER,"
"salary REAL,"
"data BLOB)";
store.ExecuteSql(sql);
return 0;
}
int OnOpen(RdbStore &store) override
{
return 0;
}
int OnUpgrade(RdbStore &store, int currentVersion, int targetVersion) override
{
return 0;
}
};
void RdbInterfaceStoreDistributedTest::SetUpTestCase()
{
int errCode = 0;
std::string path = RdbInterfaceStoreDistributedTest::DRDB_PATH + RdbInterfaceStoreDistributedTest::DRDB_NAME;
RdbHelper::DeleteRdbStore(path);
int fd = open(path.c_str(), O_CREAT, S_IRWXU | S_IRWXG);
if (fd < 0) {
return;
}
if (fd > 0) {
close(fd);
}
chown(path.c_str(), 0, ddmsGroupId_);
RdbStoreConfig config(path);
config.SetBundleName("com.example.distributed.rdb");
config.SetName(RdbInterfaceStoreDistributedTest::DRDB_NAME);
TestOpenCallback callback;
rdbStore = RdbHelper::GetRdbStore(config, 1, callback, errCode);
EXPECT_NE(nullptr, rdbStore);
}
void RdbInterfaceStoreDistributedTest::TearDownTestCase()
{
RdbHelper::DeleteRdbStore(
RdbInterfaceStoreDistributedTest::DRDB_PATH + RdbInterfaceStoreDistributedTest::DRDB_NAME);
}
void RdbInterfaceStoreDistributedTest::SetUp()
{
EXPECT_NE(nullptr, rdbStore);
}
void RdbInterfaceStoreDistributedTest::InsertValue(std::shared_ptr<RdbStore> &store)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("data", std::vector<uint8_t>{ 1, 2, 3 });
EXPECT_EQ(E_OK, store->Insert(id, "employee", values));
EXPECT_EQ(1, id);
}
void RdbInterfaceStoreDistributedTest::CheckResultSet(std::shared_ptr<RdbStore> &store)
{
std::shared_ptr<ResultSet> resultSet =
store->QuerySql("SELECT * FROM employee WHERE name = ?", std::vector<std::string>{ "zhangsan" });
EXPECT_NE(nullptr, resultSet);
int columnIndex;
int intVal;
std::string strVal;
ColumnType columnType;
int position;
int ret = resultSet->GetRowIndex(position);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(-1, position);
ret = resultSet->GetColumnType(0, columnType);
EXPECT_EQ(E_ROW_OUT_RANGE, ret);
ret = resultSet->GoToFirstRow();
EXPECT_EQ(E_OK, ret);
ret = resultSet->GetColumnIndex("id", columnIndex);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(0, columnIndex);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(1, intVal);
ret = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(E_OK, ret);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ColumnType::TYPE_STRING, columnType);
ret = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ("zhangsan", strVal);
}
* @tc.name: RdbStore_Distributed_Test_001
* @tc.desc: test RdbStore set distributed tables
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceStoreDistributedTest, RdbStore_Distributed_001, TestSize.Level1)
{
EXPECT_NE(nullptr, rdbStore);
InsertValue(rdbStore);
CheckResultSet(rdbStore);
}
* @tc.name: RdbStore_Distributed_Test_002
* @tc.desc: Abnormal testCase of ObtainDistributedTableName, if networkId is ""
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceStoreDistributedTest, RdbStore_Distributed_002, TestSize.Level2)
{
EXPECT_NE(nullptr, rdbStore);
int errCode;
EXPECT_EQ("", rdbStore->ObtainDistributedTableName("", "employee", errCode));
EXPECT_EQ(E_ERROR, errCode);
}
* @tc.name: RdbStore_Distributed_Test_003
* @tc.desc: Abnormal testCase of ObtainDistributedTableName, if networkId is invalid
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceStoreDistributedTest, RdbStore_Distributed_003, TestSize.Level2)
{
EXPECT_NE(nullptr, rdbStore);
int errCode;
EXPECT_EQ("", rdbStore->ObtainDistributedTableName("123456", "employee", errCode));
EXPECT_EQ(E_ERROR, errCode);
}
* @tc.name: RdbStore_Distributed_Test_004
* @tc.desc: Abnormal testCase of SetDistributedTables
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceStoreDistributedTest, RdbStore_Distributed_Test_004, TestSize.Level2)
{
int errCode;
std::vector<std::string> tables;
OHOS::DistributedRdb::DistributedConfig distributedConfig;
errCode = rdbStore->SetDistributedTables(tables, 1, distributedConfig);
EXPECT_EQ(E_OK, errCode);
tables.push_back("employee");
errCode = rdbStore->SetDistributedTables(tables, 1, distributedConfig);
EXPECT_NE(E_OK, errCode);
std::string path = RdbInterfaceStoreDistributedTest::DRDB_PATH + "test.db";
RdbHelper::DeleteRdbStore(path);
RdbStoreConfig config(path);
TestOpenCallback callback;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, callback, errCode);
EXPECT_NE(nullptr, store);
errCode = store->SetDistributedTables(tables, 1, distributedConfig);
EXPECT_EQ(E_INVALID_ARGS, errCode);
RdbHelper::DeleteRdbStore(path);
}
* @tc.name: RdbStore_Distributed_Test_005
* @tc.desc: Normal testCase of Sync
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceStoreDistributedTest, RdbStore_Distributed_Test_005, TestSize.Level2)
{
int errCode;
OHOS::DistributedRdb::SyncOption option = { OHOS::DistributedRdb::TIME_FIRST, false };
AbsRdbPredicates predicate("employee");
std::vector<std::string> tables;
errCode = rdbStore->Sync(option, predicate, OHOS::DistributedRdb::AsyncBrief());
EXPECT_EQ(E_OK, errCode);
errCode = rdbStore->Sync(option, tables, OHOS::DistributedRdb::AsyncDetail());
EXPECT_EQ(E_OK, errCode);
errCode = rdbStore->Sync(option, predicate, OHOS::DistributedRdb::AsyncDetail());
EXPECT_EQ(E_OK, errCode);
std::string path = RdbInterfaceStoreDistributedTest::DRDB_PATH + "test.db";
RdbStoreConfig config(path);
TestOpenCallback callback;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, callback, errCode);
EXPECT_NE(nullptr, store);
errCode = store->Sync(option, predicate, OHOS::DistributedRdb::AsyncBrief());
EXPECT_EQ(E_INVALID_ARGS, errCode);
errCode = store->Sync(option, tables, nullptr);
EXPECT_EQ(E_INVALID_ARGS, errCode);
RdbHelper::DeleteRdbStore(path);
}