From 7a8c3b5a1bd95ebf7d96c81dc645cad91e40bad0 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Wed, 10 Dec 2025 09:44:27 +0200 Subject: [PATCH 001/171] sm: tests: add UT Signed-off-by: Mykola Solianko Reviewed-by: Mykola Kobets Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko --- src/sm/smclient/tests/CMakeLists.txt | 2 +- src/sm/smclient/tests/smclient.cpp | 1586 +++++++++++--------------- 2 files changed, 649 insertions(+), 939 deletions(-) diff --git a/src/sm/smclient/tests/CMakeLists.txt b/src/sm/smclient/tests/CMakeLists.txt index 9256f4703..941af06a3 100644 --- a/src/sm/smclient/tests/CMakeLists.txt +++ b/src/sm/smclient/tests/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES smclient.cpp) # Libraries # ###################################################################################################################### -set(LIBRARIES aos::sm::smclient aos::sm::tests::mocks aos::common::tests::utils GTest::gmock_main) +set(LIBRARIES aos::sm::smclient aos::common::tests::mocks aos::common::tests::utils GTest::gmock_main) # ###################################################################################################################### # Target diff --git a/src/sm/smclient/tests/smclient.cpp b/src/sm/smclient/tests/smclient.cpp index 6743ca9f8..9d52aa8af 100644 --- a/src/sm/smclient/tests/smclient.cpp +++ b/src/sm/smclient/tests/smclient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 EPAM Systems, Inc. + * Copyright (C) 2025 EPAM Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,367 +9,29 @@ #include #include #include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include + +#include #include #include #include - -#include - -#include #include +#include +#include +#include +#include +#include +#include using namespace testing; using namespace aos; /*********************************************************************************************************************** - * Test utils - **********************************************************************************************************************/ - -namespace common::v1 { - -bool operator==(const ErrorInfo& lhs, const ErrorInfo& rhs) -{ - return google::protobuf::util::MessageDifferencer::Equals(lhs, rhs); -} - -} // namespace common::v1 - -namespace servicemanager::v4 { -bool operator==(const smproto::NodeConfigStatus& lhs, const smproto::NodeConfigStatus& rhs) -{ - return google::protobuf::util::MessageDifferencer::Equals(lhs, rhs); -} - -} // namespace servicemanager::v4 - -namespace { - -aos::NodeInfoObsolete CreateNodeInfo() -{ - aos::NodeInfoObsolete result; - - result.mNodeID = "test-node-id"; - - return result; -} - -aos::monitoring::NodeMonitoringData CreateNodeMonitoringData() -{ - aos::monitoring::NodeMonitoringData monitoringData; - - monitoringData.mNodeID = "test-node-id"; - monitoringData.mMonitoringData.mCPU = 1; - monitoringData.mMonitoringData.mRAM = 2; - monitoringData.mMonitoringData.mDownload = 3; - monitoringData.mMonitoringData.mUpload = 4; - - return monitoringData; -} - -aos::AlertVariant CreateAlert() -{ - aos::AlertVariant result; - aos::SystemAlert systemAlert; - - systemAlert.mMessage = "test-message"; - - result.SetValue(systemAlert); - - return result; -} - -aos::PushLog CreatePushLog() -{ - aos::PushLog log; - - log.mContent = "test log"; - log.mLogID = "test-log-id"; - log.mPart = 0; - log.mPartsCount = 1; - - return log; -} - -aos::InstanceStatusArray CreateInstanceStatus() -{ - aos::InstanceStatusArray instances; - aos::InstanceStatus instance; - - static_cast(instance) = aos::InstanceIdent {"service-id", "instance-id", 0}; - instance.mState = aos::InstanceStateEnum::eActive; - instance.mVersion = "1.0.0"; - - instances.PushBack(instance); - - return instances; -} - -} // namespace - -/*********************************************************************************************************************** - * Suite + * Test fixture **********************************************************************************************************************/ -class TestSMService : public smproto::SMService::Service { -public: - TestSMService(const std::string& url) { mServer = CreateServer(url, grpc::InsecureServerCredentials()); } - - ~TestSMService() - { - if (mCtx) { - mCtx->TryCancel(); - } - } - - grpc::Status RegisterSM(grpc::ServerContext* context, - grpc::ServerReaderWriter* stream) override - { - LOG_INF() << "Test server message thread started"; - - try { - - mStream = stream; - mCtx = context; - - smproto::SMOutgoingMessages incomingMsg; - - while (stream->Read(&incomingMsg)) { - { - if (incomingMsg.has_node_config_status()) { - std::lock_guard lock {mLock}; - - OnNodeConfigStatus(incomingMsg.node_config_status()); - - mNodeConfigStatusReceived = true; - mNodeConfigStatusCV.notify_all(); - continue; - } else if (incomingMsg.has_run_instances_status()) { - OnRunInstancesStatus(incomingMsg.run_instances_status()); - } else if (incomingMsg.has_update_instances_status()) { - OnUpdateInstancesStatus(incomingMsg.update_instances_status()); - } else if (incomingMsg.has_override_env_var_status()) { - OnOverrideEnvVarStatus(incomingMsg.override_env_var_status()); - } else if (incomingMsg.has_log()) { - OnLogData(incomingMsg.log()); - } else if (incomingMsg.has_instant_monitoring()) { - OnInstantMonitoring(incomingMsg.instant_monitoring()); - } else if (incomingMsg.has_average_monitoring()) { - OnAverageMonitoring(incomingMsg.average_monitoring()); - } else if (incomingMsg.has_alert()) { - OnAlert(incomingMsg.alert()); - } else if (incomingMsg.has_image_content_request()) { - OnImageContentRequest(incomingMsg.image_content_request()); - } else if (incomingMsg.has_clock_sync_request()) { - OnClockSyncRequest(incomingMsg.clock_sync_request()); - } else { - LOG_ERR() << "Unknown message received in test server"; - - continue; - } - - { - std::lock_guard lock {mLock}; - - mResponseCV.notify_all(); - mResponseReceived = true; - } - } - } - } catch (const std::exception& e) { - LOG_ERR() << e.what(); - } - - LOG_DBG() << "Test server message thread stoped"; - - mStream = nullptr; - mCtx = nullptr; - - return grpc::Status::OK; - } - - MOCK_METHOD(void, OnNodeConfigStatus, (const smproto::NodeConfigStatus&)); - MOCK_METHOD(void, OnRunInstancesStatus, (const smproto::RunInstancesStatus&)); - MOCK_METHOD(void, OnUpdateInstancesStatus, (const smproto::UpdateInstancesStatus&)); - MOCK_METHOD(void, OnOverrideEnvVarStatus, (const smproto::OverrideEnvVarStatus&)); - MOCK_METHOD(void, OnLogData, (const smproto::LogData&)); - MOCK_METHOD(void, OnInstantMonitoring, (const smproto::InstantMonitoring&)); - MOCK_METHOD(void, OnAverageMonitoring, (const smproto::AverageMonitoring&)); - MOCK_METHOD(void, OnAlert, (const smproto::Alert&)); - MOCK_METHOD(void, OnImageContentRequest, (const smproto::ImageContentRequest&)); - MOCK_METHOD(void, OnClockSyncRequest, (const smproto::ClockSyncRequest&)); - - void GetNodeConfigStatus() - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_get_node_config_status(); - - mStream->Write(incomingMsg); - } - - void CheckNodeConfig(const std::string& version, const std::string& config) - { - smproto::SMIncomingMessages incomingMsg; - - auto checkNodeConfig = incomingMsg.mutable_check_node_config(); - - checkNodeConfig->set_version(version); - checkNodeConfig->set_node_config(config); - - mStream->Write(incomingMsg); - } - - void SetNodeConfig(const std::string& version, const std::string& config) - { - smproto::SMIncomingMessages incomingMsg; - - auto setNodeConfig = incomingMsg.mutable_set_node_config(); - - setNodeConfig->set_version(version); - setNodeConfig->set_node_config(config); - - mStream->Write(incomingMsg); - } - - void RunInstances(const servicemanager::v4::RunInstances& runInstances = servicemanager::v4::RunInstances {}) - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_run_instances()->CopyFrom(runInstances); - - mStream->Write(incomingMsg); - } - - void UpdateNetwork(const servicemanager::v4::UpdateNetworks& updateNetwork = servicemanager::v4::UpdateNetworks {}) - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_update_networks()->CopyFrom(updateNetwork); - - mStream->Write(incomingMsg); - } - - void GetSystemLog() - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_system_log_request(); - - mStream->Write(incomingMsg); - } - - void GetInstanceLog() - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_instance_log_request(); - - mStream->Write(incomingMsg); - } - - void GetInstanceCrashLog() - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_instance_crash_log_request(); - - mStream->Write(incomingMsg); - } - - void OverrideEnvVars( - const servicemanager::v4::OverrideEnvVars& overrideEnvVars = servicemanager::v4::OverrideEnvVars {}) - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_override_env_vars()->CopyFrom(overrideEnvVars); - - mStream->Write(incomingMsg); - } - - void GetAverageMonitoring() - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_get_average_monitoring(); - - mStream->Write(incomingMsg); - } - - void SendConnectionStatus(smproto::ConnectionEnum status = smproto::ConnectionEnum::CONNECTED) - { - smproto::SMIncomingMessages incomingMsg; - - incomingMsg.mutable_connection_status()->set_cloud_status(status); - - mStream->Write(incomingMsg); - } - - void WaitNodeConfigStatus(const std::chrono::seconds& timeout = std::chrono::seconds(4)) - { - std::unique_lock lock {mLock}; - - mNodeConfigStatusCV.wait_for(lock, timeout, [this] { return mNodeConfigStatusReceived; }); - - mNodeConfigStatusReceived = false; - } - - void WaitMessage(const std::chrono::seconds& timeout = std::chrono::seconds(4)) - { - std::unique_lock lock {mLock}; - - mResponseCV.wait_for(lock, timeout, [this] { return mResponseReceived; }); - - mResponseReceived = false; - } - - aos::Error SendMessage(const smproto::SMIncomingMessages& msg) - { - if (!mStream) { - return AOS_ERROR_WRAP(aos::Error(ErrorEnum::eFailed, "stream is not initialized")); - } - - if (!mStream->Write(msg)) { - return AOS_ERROR_WRAP(aos::Error(ErrorEnum::eFailed, "can't send message")); - } - - return aos::ErrorEnum::eNone; - } - -private: - std::unique_ptr CreateServer( - const std::string& addr, const std::shared_ptr& credentials) - { - grpc::ServerBuilder builder; - - builder.AddListeningPort(addr, credentials); - builder.RegisterService(static_cast(this)); - - return builder.BuildAndStart(); - } - - grpc::ServerReaderWriter* mStream = nullptr; - grpc::ServerContext* mCtx = nullptr; - - std::mutex mLock; - std::condition_variable mNodeConfigStatusCV; - std::condition_variable mResponseCV; - - bool mNodeConfigStatusReceived = false; - bool mResponseReceived = false; - - std::unique_ptr mServer; -}; - class SMClientTest : public Test { protected: void SetUp() override { tests::utils::InitLog(); } @@ -378,756 +40,804 @@ class SMClientTest : public Test { { sm::smclient::Config config; - config.mCMServerURL = "localhost:5555"; + config.mCMServerURL = "localhost:5556"; config.mCertStorage = "sm"; config.mCMReconnectTimeout = 100 * Time::cMilliseconds; return config; } - std::unique_ptr CreateClient( - const sm::smclient::Config& config = GetConfig(), bool secureConnection = false) + auto CreateRuntimeInfos() { - auto client = std::make_unique(); - - auto err = client->Init(config, mTLSCredentials, mNodeInfoProvider, mResourceManager, mNetworkManager, - mLogProvider, mResourceMonitor, mLauncher, secureConnection); + auto runtimes = std::make_unique(); + RuntimeInfo runtime; - if (!err.IsNone()) { - LOG_ERR() << "Can't init client: error=" << err.Message(); + runtime.mRuntimeID = "runtime1"; + runtime.mRuntimeType = "runc"; + runtime.mMaxDMIPS.SetValue(1000); + runtime.mAllowedDMIPS.SetValue(800); + runtime.mTotalRAM.SetValue(1024 * 1024 * 1024); + runtime.mAllowedRAM.SetValue(512 * 1024 * 1024); + runtime.mMaxInstances = 10; - return nullptr; - } + runtimes->PushBack(runtime); - return client; + return runtimes; } - std::unique_ptr CreateServer(const std::string& url) { return std::make_unique(url); } - - std::pair, std::unique_ptr> InitTest( - const sm::smclient::Config& config = GetConfig(), bool provisionMode = true) + auto CreateResourceInfos() { - auto server = CreateServer(config.mCMServerURL); - auto client = CreateClient(config); - - NodeInfoObsolete nodeInfo = CreateNodeInfo(); - RetWithError> nodeConfigVersion = {"1.0.0", ErrorEnum::eNone}; - smproto::NodeConfigStatus expNodeConfigVersion; - - expNodeConfigVersion.set_node_id(nodeInfo.mNodeID.CStr()); - expNodeConfigVersion.set_node_type(nodeInfo.mNodeType.CStr()); - expNodeConfigVersion.set_version(nodeConfigVersion.mValue.CStr()); - - EXPECT_CALL(mNodeInfoProvider, GetNodeInfo) - .WillRepeatedly(DoAll(SetArgReferee<0>(nodeInfo), Return(ErrorEnum::eNone))); - EXPECT_CALL(mLauncher, GetCurrentRunStatus).WillRepeatedly(Return(ErrorEnum::eNone)); - EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials) - .WillRepeatedly(Return(std::shared_ptr())); - EXPECT_CALL(mResourceManager, GetNodeConfigVersion).WillRepeatedly(Return(nodeConfigVersion)); - EXPECT_CALL(*server, OnNodeConfigStatus(expNodeConfigVersion)).Times(1); - - if (!provisionMode) { - EXPECT_CALL(mTLSCredentials, SubscribeListener).WillOnce(Return(ErrorEnum::eNone)); - EXPECT_CALL(mTLSCredentials, UnsubscribeListener).WillOnce(Return(ErrorEnum::eNone)); - } + auto resources = std::make_unique>(); + sm::resourcemanager::ResourceInfo resource; - EXPECT_CALL(mLogProvider, Subscribe(_)).WillOnce(Return(Error())); + resource.mName = "resource1"; + resource.mSharedCount = 2; - if (auto err = client->Start(); !err.IsNone()) { - LOG_ERR() << "Can't start client: error=" << err.Message(); + resources->PushBack(resource); - return std::make_pair(nullptr, nullptr); - } + return resources; + } + + auto CreateInstanceStatuses() + { + auto statuses = std::make_unique(); + InstanceStatus status; - server->WaitNodeConfigStatus(); - server->WaitMessage(); + static_cast(status) = InstanceIdent {"service1", "subject1", 0, UpdateItemTypeEnum::eService}; + status.mVersion = "1.0.0"; + status.mPreinstalled = false; + status.mRuntimeID = "runtime1"; + status.mManifestDigest = "sha256:1234567890"; + status.mState = InstanceStateEnum::eActive; - return std::make_pair(std::move(server), std::move(client)); + statuses->PushBack(status); + + return statuses; } - aos::common::iamclient::TLSCredentialsMock mTLSCredentials; - iam::nodeinfoprovider::NodeInfoProviderMock mNodeInfoProvider; - sm::resourcemanager::ResourceManagerMock mResourceManager; - sm::networkmanager::NetworkManagerMock mNetworkManager; - sm::logprovider::LogProviderMock mLogProvider; - monitoring::ResourceMonitorMock mResourceMonitor; - sm::launcher::LauncherMock mLauncher; + testing::NiceMock mTLSCredentials; + testing::NiceMock mCertProvider; + testing::NiceMock mRuntimeInfoProvider; + testing::NiceMock mResourceInfoProvider; + testing::NiceMock mNodeConfigHandler; + testing::NiceMock mLauncher; + testing::NiceMock mLogProvider; + testing::NiceMock mNetworkManager; + testing::NiceMock mMonitoring; + testing::NiceMock mInstanceStatusProvider; }; /*********************************************************************************************************************** * Tests **********************************************************************************************************************/ -TEST_F(SMClientTest, ClientNotStarted) +TEST_F(SMClientTest, RegisterSMSucceeds) { - auto server = CreateServer(GetConfig().mCMServerURL); - ASSERT_NE(server, nullptr) << "Can't create server"; - - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - EXPECT_CALL(*server, OnNodeConfigStatus).Times(0); - server->WaitNodeConfigStatus(std::chrono::seconds(1)); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Stop should return no error if start wasn't called" << err.Message(); -} - -TEST_F(SMClientTest, SecondStartReturnsError) -{ - auto [server, client] = InitTest(); - - auto err = client->Start(); - ASSERT_TRUE(err.Is(aos::ErrorEnum::eFailed)) - << "Start should return failed if client isn't closed" << err.Message(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectOnGettingUnhandlerMessage) -{ - auto config = GetConfig(); - - config.mCMReconnectTimeout = 10 * Time::cMilliseconds; - - auto [server, client] = InitTest(config); - - server->SendMessage(smproto::SMIncomingMessages()); - - // Client is expected to reconnect and send node config status - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - server->WaitNodeConfigStatus(std::chrono::seconds(3)); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, StartFailsOnGetNodeInfoError) -{ - auto server = CreateServer(GetConfig().mCMServerURL); - ASSERT_NE(server, nullptr) << "Can't create server"; - - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; - - EXPECT_CALL(mNodeInfoProvider, GetNodeInfo).WillOnce(Return(aos::ErrorEnum::eFailed)); - - auto err = client->Start(); - ASSERT_TRUE(err.Is(aos::ErrorEnum::eFailed)) - << "Start should return failed if get node info fails: error=" << err.Message(); -} + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); -TEST_F(SMClientTest, SendMonitoringDataSucceeds) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(*server, OnSMInfo(_)).WillOnce(Invoke([](const smproto::SMInfo& info) { + EXPECT_EQ(info.node_id(), "test-node"); + EXPECT_EQ(info.runtimes_size(), 1); + EXPECT_EQ(info.runtimes(0).runtime_id(), "runtime1"); + EXPECT_EQ(info.runtimes(0).type(), "runc"); + EXPECT_EQ(info.resources_size(), 1); + EXPECT_EQ(info.resources(0).name(), "resource1"); + })); - EXPECT_CALL(*server, OnInstantMonitoring).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).WillOnce(Invoke([](const smproto::NodeInstancesStatus& status) { + EXPECT_EQ(status.instances_size(), 1); + EXPECT_EQ(status.instances(0).instance().item_id(), "service1"); + EXPECT_EQ(status.instances(0).version(), "1.0.0"); + })); - auto err = client->SendMonitoringData(CreateNodeMonitoringData()); - EXPECT_TRUE(err.IsNone()) << "Can't send monitoring data: error=" << err.Message(); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->WaitMessage(); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, SendMonitoringDataReturnsErrorIfNotConnected) +TEST_F(SMClientTest, SendSMInfoWithMultipleRuntimesAndResources) { - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - auto err = client->SendMonitoringData(CreateNodeMonitoringData()); - EXPECT_TRUE(err.Is(aos::ErrorEnum::eFailed)) << "Client should fail: error=" << err.Message(); -} - -TEST_F(SMClientTest, SendAlertSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnAlert).Times(1); - - auto err = client->SendAlert(CreateAlert()); - EXPECT_TRUE(err.IsNone()) << "Can't send alerts: error=" << err.Message(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + auto runtimes = std::make_unique(); + for (int i = 0; i < 3; i++) { + RuntimeInfo runtime; + runtime.mRuntimeID = (std::string("runtime") + std::to_string(i)).c_str(); + runtime.mRuntimeType = "runc"; + runtimes->PushBack(runtime); + } - err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + auto resources = std::make_unique>(); + for (int i = 0; i < 2; i++) { + sm::resourcemanager::ResourceInfo resource; + resource.mName = (std::string("resource") + std::to_string(i)).c_str(); + resources->PushBack(resource); + } -TEST_F(SMClientTest, SendAlertReturnsErrorIfNotConnected) -{ - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; + auto statuses = CreateInstanceStatuses(); - auto err = client->SendAlert(CreateAlert()); - EXPECT_TRUE(err.Is(aos::ErrorEnum::eFailed)) << "Client should fail: error=" << err.Message(); -} + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); -TEST_F(SMClientTest, OnLogReceivedSucceeds) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(*server, OnSMInfo(_)).WillOnce(Invoke([](const smproto::SMInfo& info) { + EXPECT_EQ(info.runtimes_size(), 3); + EXPECT_EQ(info.resources_size(), 2); + })); - EXPECT_CALL(*server, OnLogData).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); - auto err = client->OnLogReceived(CreatePushLog()); - EXPECT_TRUE(err.IsNone()) << "Can't send log data: error=" << err.Message(); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->WaitMessage(); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitSMInfo(); err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, OnLogReceivedReturnsErrorIfNotConnected) +TEST_F(SMClientTest, SendNodeInstancesStatusWithMultipleInstances) { - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; - - auto err = client->OnLogReceived(CreatePushLog()); - EXPECT_TRUE(err.Is(aos::ErrorEnum::eFailed)) << "Client should fail: error=" << err.Message(); -} - -TEST_F(SMClientTest, InstancesRunStatusSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - - auto err = client->InstancesRunStatus(CreateInstanceStatus()); - EXPECT_TRUE(err.IsNone()) << "Can't send instance run status: error=" << err.Message(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - server->WaitMessage(); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + auto statuses = std::make_unique(); + for (int i = 0; i < 3; i++) { + InstanceStatus status; + static_cast(status) = InstanceIdent {(std::string("service") + std::to_string(i)).c_str(), + "subject1", static_cast(i), UpdateItemTypeEnum::eService}; + status.mVersion = "1.0.0"; + status.mRuntimeID = "runtime1"; + status.mState = InstanceStateEnum::eActive; + statuses->PushBack(status); + } -TEST_F(SMClientTest, InstancesRunStatusReturnsErrorIfNotConnected) -{ - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - auto err = client->InstancesRunStatus(CreateInstanceStatus()); - EXPECT_TRUE(err.Is(aos::ErrorEnum::eFailed)) << "Client should fail: error=" << err.Message(); -} + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); -TEST_F(SMClientTest, InstancesUpdateStatusSucceeds) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).WillOnce(Invoke([](const smproto::NodeInstancesStatus& status) { + EXPECT_EQ(status.instances_size(), 3); + EXPECT_EQ(status.instances(0).instance().item_id(), "service0"); + EXPECT_EQ(status.instances(1).instance().item_id(), "service1"); + EXPECT_EQ(status.instances(2).instance().item_id(), "service2"); + })); - auto err = client->InstancesUpdateStatus(CreateInstanceStatus()); - EXPECT_TRUE(err.IsNone()) << "Can't send instance update status: error=" << err.Message(); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->WaitMessage(std::chrono::seconds(1)); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitNodeInstancesStatus(); err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, InstancesUpdateStatusReturnsErrorIfNotConnected) -{ - auto client = CreateClient(); - ASSERT_NE(client, nullptr) << "Can't create client"; - - auto err = client->InstancesUpdateStatus(CreateInstanceStatus()); - EXPECT_TRUE(err.Is(aos::ErrorEnum::eFailed)) << "Client should fail: error=" << err.Message(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, GetNodeConfigStatusSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - - server->GetNodeConfigStatus(); - - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, CheckNodeConfigSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(mResourceManager, CheckNodeConfig).WillOnce(Return(ErrorEnum::eNone)); - - server->CheckNodeConfig("1.0.1", "{}"); - - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, SetNodeConfigSucceeds) +TEST_F(SMClientTest, ClientNotStarted) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(mResourceManager, UpdateNodeConfig).WillOnce(Return(ErrorEnum::eNone)); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->SetNodeConfig("1.0.1", "{}"); + EXPECT_CALL(*server, OnSMInfo(_)).Times(0); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(0); - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop should return no error if start wasn't called"; } -TEST_F(SMClientTest, RunInstancesSucceeds) +TEST_F(SMClientTest, SecondStartReturnsError) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - EXPECT_CALL(mLauncher, RunInstances).WillOnce(Invoke([&] { - client->InstancesRunStatus(CreateInstanceStatus()); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } return ErrorEnum::eNone; })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - server->RunInstances(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectsOnRunInstancesServicesExceedsLimit) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - EXPECT_CALL(mLauncher, RunInstances).Times(0); - - servicemanager::v4::RunInstances runInstances; - for (size_t i = 0; i < aos::cMaxNumServices + 1; ++i) { - runInstances.add_services(); - } - - server->RunInstances(runInstances); - - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectsOnRunInstancesLayersExceedsLimit) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - EXPECT_CALL(mLauncher, RunInstances).Times(0); - - servicemanager::v4::RunInstances runInstances; - for (size_t i = 0; i < aos::cMaxNumLayers + 1; ++i) { - runInstances.add_layers(); - } - - server->RunInstances(runInstances); - - server->WaitNodeConfigStatus(); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectsOnRunInstancesInstancesExceedsLimit) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - EXPECT_CALL(mLauncher, RunInstances).Times(0); - - servicemanager::v4::RunInstances runInstances; - for (size_t i = 0; i < aos::cMaxNumInstances + 1; ++i) { - runInstances.add_instances(); - } - - server->RunInstances(runInstances); - - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectsOnRunInstancesLauncherError) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnRunInstancesStatus).Times(1); - EXPECT_CALL(mLauncher, RunInstances).WillOnce(Return(aos::ErrorEnum::eFailed)); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->RunInstances(); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "First Start failed"; - server->WaitNodeConfigStatus(); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + err = client->Start(); + EXPECT_TRUE(err.Is(ErrorEnum::eFailed)) << "Second Start should fail"; - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, UpdateNetworkSucceeds) +TEST_F(SMClientTest, SendNodeInstancesStatusesCallback) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - std::promise promise; - - EXPECT_CALL(mNetworkManager, UpdateNetworks).WillOnce(Invoke([&] { - promise.set_value(); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } return ErrorEnum::eNone; })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - server->UpdateNetwork(); - - auto status = promise.get_future().wait_for(std::chrono::seconds(1)); - EXPECT_EQ(status, std::future_status::ready) << "network manager wasn't called"; - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(AtLeast(1)); -TEST_F(SMClientTest, ClientReconnectsOnUpdateNetworkManagerError) -{ - auto [server, client] = InitTest(); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(mNetworkManager, UpdateNetworks).WillOnce(Return(aos::ErrorEnum::eFailed)); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - server->UpdateNetwork(); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - server->WaitNodeConfigStatus(); + InstanceStatusArray callbackStatuses; + InstanceStatus status; + static_cast(status) + = InstanceIdent {"callback-service", "subject1", 1, UpdateItemTypeEnum::eService}; + status.mVersion = "2.0.0"; + status.mRuntimeID = "runtime1"; + status.mState = InstanceStateEnum::eActive; + callbackStatuses.PushBack(status); - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + err = client->SendNodeInstancesStatuses(callbackStatuses); + ASSERT_TRUE(err.IsNone()) << "SendNodeInstancesStatuses failed"; - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, GetSystemLogSucceeds) +TEST_F(SMClientTest, SendUpdateInstancesStatusesCallback) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - EXPECT_CALL(*server, OnLogData).Times(1); - EXPECT_CALL(mLogProvider, GetSystemLog).WillOnce(Invoke([&] { - client->OnLogReceived(CreatePushLog()); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } return ErrorEnum::eNone; })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - server->GetSystemLog(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); + EXPECT_CALL(*server, OnUpdateInstancesStatus(_)).Times(1); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; -TEST_F(SMClientTest, ClientReconnectsOnGetSystemLogProviderError) -{ - auto [server, client] = InitTest(); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnLogData).Times(0); - EXPECT_CALL(mLogProvider, GetSystemLog).WillOnce(Return(aos::ErrorEnum::eFailed)); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - server->GetSystemLog(); + InstanceStatusArray updateStatuses; + InstanceStatus status; + static_cast(status) = InstanceIdent {"update-service", "subject1", 2, UpdateItemTypeEnum::eService}; + status.mVersion = "3.0.0"; + status.mRuntimeID = "runtime1"; + status.mState = InstanceStateEnum::eActive; + updateStatuses.PushBack(status); - server->WaitNodeConfigStatus(); + client->SendUpdateInstancesStatuses(updateStatuses); - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitUpdateInstancesStatus(); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, GetInstanceLogSucceeds) +TEST_F(SMClientTest, SendMonitoringData) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - EXPECT_CALL(*server, OnLogData).Times(1); - EXPECT_CALL(mLogProvider, GetInstanceLog).WillOnce(Invoke([&] { - client->OnLogReceived(CreatePushLog()); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } return ErrorEnum::eNone; })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - server->GetInstanceLog(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ClientReconnectsOnGetInstanceLogProviderError) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnLogData).Times(0); - EXPECT_CALL(mLogProvider, GetInstanceLog).WillOnce(Return(aos::ErrorEnum::eFailed)); - - server->GetInstanceLog(); - - server->WaitNodeConfigStatus(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, GetInstanceCrashLogSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnLogData).Times(1); - EXPECT_CALL(mLogProvider, GetInstanceCrashLog).WillOnce(Invoke([&] { - client->OnLogReceived(CreatePushLog()); - - return ErrorEnum::eNone; + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); + EXPECT_CALL(*server, OnInstantMonitoring(_)).WillOnce(Invoke([](const smproto::InstantMonitoring& monitoring) { + EXPECT_TRUE(monitoring.has_node_monitoring()); + EXPECT_EQ(monitoring.instances_monitoring_size(), 2); + EXPECT_EQ(monitoring.instances_monitoring(0).instance().item_id(), "service1"); + EXPECT_EQ(monitoring.instances_monitoring(0).runtime_id(), "runtime1"); + EXPECT_EQ(monitoring.instances_monitoring(1).instance().item_id(), "service2"); + EXPECT_EQ(monitoring.instances_monitoring(1).runtime_id(), "runtime2"); })); - server->GetInstanceCrashLog(); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - server->WaitMessage(); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + aos::monitoring::NodeMonitoringData monitoringData; + monitoringData.mTimestamp = Time::Now(); + monitoringData.mNodeID = "test-node"; -TEST_F(SMClientTest, ClientReconnectsOnGetInstanceCrashLogProviderError) -{ - auto [server, client] = InitTest(); + monitoringData.mMonitoringData.mTimestamp = monitoringData.mTimestamp; + monitoringData.mMonitoringData.mRAM = 1024 * 1024 * 512; // 512 MB + monitoringData.mMonitoringData.mCPU = 50.5; + monitoringData.mMonitoringData.mDownload = 1000; + monitoringData.mMonitoringData.mUpload = 500; - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnLogData).Times(0); - EXPECT_CALL(mLogProvider, GetInstanceCrashLog).WillOnce(Return(aos::ErrorEnum::eFailed)); + aos::monitoring::InstanceMonitoringData instance1; + instance1.mInstanceIdent = InstanceIdent {"service1", "subject1", 0, UpdateItemTypeEnum::eService}; + instance1.mRuntimeID = "runtime1"; + instance1.mMonitoringData = monitoringData.mMonitoringData; + monitoringData.mInstances.PushBack(instance1); - server->GetInstanceCrashLog(); + aos::monitoring::InstanceMonitoringData instance2; + instance2.mInstanceIdent = InstanceIdent {"service2", "subject1", 1, UpdateItemTypeEnum::eService}; + instance2.mRuntimeID = "runtime2"; + instance2.mMonitoringData = monitoringData.mMonitoringData; + monitoringData.mInstances.PushBack(instance2); - server->WaitNodeConfigStatus(); + err = client->SendMonitoringData(monitoringData); + ASSERT_TRUE(err.IsNone()) << "SendMonitoringData failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + server->WaitInstantMonitoring(); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, OverrideEnvVarsSucceeds) +TEST_F(SMClientTest, SendAlert) { - auto [server, client] = InitTest(); + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - aos::EnvVarsInstanceStatus expectedStatus; + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); - expectedStatus.mItemID = "service-id"; - expectedStatus.mStatuses.PushBack({"var-name", aos::ErrorEnum::eNone}); - - EXPECT_CALL(*server, OnOverrideEnvVarStatus).WillOnce(Invoke([&](const smproto::OverrideEnvVarStatus& status) { - EXPECT_EQ(status.error().aos_code(), static_cast(aos::ErrorEnum::eNone)); - - EXPECT_EQ(status.env_vars_status().size(), 1); - EXPECT_EQ(status.env_vars_status(0).instance_filter().service_id(), "service-id"); - EXPECT_EQ(status.env_vars_status(0).instance_filter().instance(), 0); - - EXPECT_EQ(status.env_vars_status(0).statuses().size(), 1); - EXPECT_EQ(status.env_vars_status(0).statuses(0).name(), "var-name"); - EXPECT_EQ( - status.env_vars_status(0).statuses(0).error().aos_code(), static_cast(aos::ErrorEnum::eNone)); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } + return ErrorEnum::eNone; })); - - EXPECT_CALL(mLauncher, OverrideEnvVars) - .WillOnce(Invoke([&](const auto& envVarsInstanceInfos, auto& envVarStatuses) { - (void)envVarsInstanceInfos; - - envVarStatuses.PushBack(expectedStatus); - - return aos::ErrorEnum::eNone; + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; })); - server->OverrideEnvVars(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, OverrideEnvVarsRequestExceedsApplicationLimit) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); + + EXPECT_CALL(*server, OnAlert(_)) + .Times(6) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // SystemAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_system_alert()); + EXPECT_EQ(alert.system_alert().message(), "System alert message"); + })) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // CoreAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_core_alert()); + EXPECT_EQ(alert.core_alert().core_component(), "SM"); + EXPECT_EQ(alert.core_alert().message(), "Core alert message"); + })) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // SystemQuotaAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_system_quota_alert()); + EXPECT_EQ(alert.system_quota_alert().parameter(), "ram"); + EXPECT_EQ(alert.system_quota_alert().value(), 1024); + EXPECT_EQ(alert.system_quota_alert().status(), "raise"); + })) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // InstanceQuotaAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_instance_quota_alert()); + EXPECT_EQ(alert.instance_quota_alert().instance().item_id(), "service1"); + EXPECT_EQ(alert.instance_quota_alert().parameter(), "cpu"); + EXPECT_EQ(alert.instance_quota_alert().value(), 90); + EXPECT_EQ(alert.instance_quota_alert().status(), "raise"); + })) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // ResourceAllocateAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_resource_allocate_alert()); + EXPECT_EQ(alert.resource_allocate_alert().instance().item_id(), "service1"); + EXPECT_EQ(alert.resource_allocate_alert().resource(), "gpu"); + EXPECT_EQ(alert.resource_allocate_alert().message(), "Resource allocation failed"); + })) + .WillOnce(Invoke([](const smproto::Alert& alert) { + // InstanceAlert + EXPECT_TRUE(alert.has_timestamp()); + EXPECT_TRUE(alert.has_instance_alert()); + EXPECT_EQ(alert.instance_alert().instance().item_id(), "service1"); + EXPECT_EQ(alert.instance_alert().service_version(), "1.0.0"); + EXPECT_EQ(alert.instance_alert().message(), "Instance alert message"); + })); - EXPECT_CALL(*server, OnOverrideEnvVarStatus).WillOnce(Invoke([&](const smproto::OverrideEnvVarStatus& status) { - EXPECT_EQ(status.error().aos_code(), static_cast(aos::ErrorEnum::eNoMemory)); - })); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - EXPECT_CALL(mLauncher, OverrideEnvVars).Times(0); + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - servicemanager::v4::OverrideEnvVars overrideEnvVarsRequest; + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - for (size_t i = 0; i < aos::cMaxNumInstances + 1; ++i) { - overrideEnvVarsRequest.add_env_vars(); + // Send SystemAlert + { + SystemAlert alert; + alert.mTimestamp = Time::Now(); + alert.mNodeID = "test-node"; + alert.mMessage = "System alert message"; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(SystemAlert) failed"; + server->WaitAlert(); } - server->OverrideEnvVars(overrideEnvVarsRequest); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, OverrideEnvVarsLauncherFails) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnOverrideEnvVarStatus).WillOnce(Invoke([&](const smproto::OverrideEnvVarStatus& status) { - EXPECT_EQ(status.error().aos_code(), static_cast(aos::ErrorEnum::eFailed)); - })); - EXPECT_CALL(mLauncher, OverrideEnvVars).WillOnce(Return(aos::ErrorEnum::eFailed)); - - server->OverrideEnvVars(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, GetAverageMonitoringSucceeds) -{ - auto [server, client] = InitTest(); - - EXPECT_CALL(*server, OnAverageMonitoring).Times(1); - EXPECT_CALL(mResourceMonitor, GetAverageMonitoringData) - .WillOnce(DoAll(SetArgReferee<0>(CreateNodeMonitoringData()), Return(aos::ErrorEnum::eNone))); - server->GetAverageMonitoring(); - - server->WaitMessage(); - - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} + // Send CoreAlert + { + CoreAlert alert; + alert.mTimestamp = Time::Now(); + alert.mNodeID = "test-node"; + alert.mCoreComponent = CoreComponentEnum::eSM; + alert.mMessage = "Core alert message"; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(CoreAlert) failed"; + server->WaitAlert(); + } -TEST_F(SMClientTest, ClientReconnectsOnGetAverageMonitoringError) -{ - auto [server, client] = InitTest(); + // Send SystemQuotaAlert + { + SystemQuotaAlert alert; + alert.mTimestamp = Time::Now(); + alert.mNodeID = "test-node"; + alert.mParameter = "ram"; + alert.mValue = 1024; + alert.mState = QuotaAlertStateEnum::eRaise; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(SystemQuotaAlert) failed"; + server->WaitAlert(); + } - EXPECT_CALL(*server, OnNodeConfigStatus).Times(1); - EXPECT_CALL(*server, OnAverageMonitoring).Times(0); - EXPECT_CALL(mResourceMonitor, GetAverageMonitoringData).WillOnce(Return(aos::ErrorEnum::eFailed)); - server->GetAverageMonitoring(); + // Send InstanceQuotaAlert + { + InstanceQuotaAlert alert; + alert.mTimestamp = Time::Now(); + static_cast(alert) = InstanceIdent {"service1", "subject1", 0, UpdateItemTypeEnum::eService}; + alert.mParameter = "cpu"; + alert.mValue = 90; + alert.mState = QuotaAlertStateEnum::eRaise; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(InstanceQuotaAlert) failed"; + server->WaitAlert(); + } - server->WaitNodeConfigStatus(); + // Send ResourceAllocateAlert + { + ResourceAllocateAlert alert; + alert.mTimestamp = Time::Now(); + alert.mNodeID = "test-node"; + static_cast(alert) = InstanceIdent {"service1", "subject1", 0, UpdateItemTypeEnum::eService}; + alert.mResource = "gpu"; + alert.mMessage = "Resource allocation failed"; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(ResourceAllocateAlert) failed"; + server->WaitAlert(); + } - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + // Send InstanceAlert + { + InstanceAlert alert; + alert.mTimestamp = Time::Now(); + static_cast(alert) = InstanceIdent {"service1", "subject1", 0, UpdateItemTypeEnum::eService}; + alert.mVersion = "1.0.0"; + alert.mMessage = "Instance alert message"; + + err = client->SendAlert(AlertVariant(alert)); + ASSERT_TRUE(err.IsNone()) << "SendAlert(InstanceAlert) failed"; + server->WaitAlert(); + } - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } -TEST_F(SMClientTest, ConnectionStatusConnectedSucceeds) +TEST_F(SMClientTest, GetBlobsInfo) { - auto [server, client] = InitTest(); - - ConnectionSubscriberMock subscriber; - - ASSERT_TRUE(client->Subscribe(subscriber).IsNone()); - - std::promise promise; - - EXPECT_CALL(subscriber, OnConnect).WillOnce(Invoke([&] { promise.set_value(); })); - - server->SendConnectionStatus(smproto::ConnectionEnum::CONNECTED); - - EXPECT_EQ(promise.get_future().wait_for(std::chrono::seconds(1)), std::future_status::ready) - << "didn't receive connection status connected"; + auto server = std::make_unique(GetConfig().mCMServerURL); + auto client = std::make_unique(); - client->Unsubscribe(subscriber); + auto runtimes = CreateRuntimeInfos(); + auto resources = CreateResourceInfos(); + auto statuses = CreateInstanceStatuses(); - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); - - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); -} - -TEST_F(SMClientTest, ConnectionStatusDisconnectedSucceeds) -{ - auto [server, client] = InitTest(); + EXPECT_CALL(mTLSCredentials, GetTLSClientCredentials(_)) + .WillRepeatedly(Return(aos::RetWithError> { + grpc::InsecureChannelCredentials(), aos::ErrorEnum::eNone})); + EXPECT_CALL(mRuntimeInfoProvider, GetRuntimesInfos(_)).WillRepeatedly(Invoke([&runtimes](Array& out) { + for (const auto& item : *runtimes) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mResourceInfoProvider, GetResourcesInfos(_)) + .WillRepeatedly(Invoke([&resources](Array& out) { + for (const auto& item : *resources) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); + EXPECT_CALL(mInstanceStatusProvider, GetInstancesStatuses(_)) + .WillRepeatedly(Invoke([&statuses](Array& out) { + for (const auto& item : *statuses) { + out.PushBack(item); + } + return ErrorEnum::eNone; + })); - ConnectionSubscriberMock subscriber; + EXPECT_CALL(*server, OnSMInfo(_)).Times(1); + EXPECT_CALL(*server, OnNodeInstancesStatus(_)).Times(1); - ASSERT_TRUE(client->Subscribe(subscriber).IsNone()); + auto err = client->Init(GetConfig(), "test-node", mTLSCredentials, mCertProvider, mRuntimeInfoProvider, + mResourceInfoProvider, mNodeConfigHandler, mLauncher, mLogProvider, mNetworkManager, mMonitoring, + mInstanceStatusProvider, false); + ASSERT_TRUE(err.IsNone()) << "Init failed"; - std::promise promise; + err = client->Start(); + ASSERT_TRUE(err.IsNone()) << "Start failed"; - EXPECT_CALL(subscriber, OnDisconnect).WillOnce(Invoke([&] { promise.set_value(); })); + server->WaitRegistered(); + server->WaitSMInfo(); + server->WaitNodeInstancesStatus(); - server->SendConnectionStatus(smproto::ConnectionEnum::DISCONNECTED); + StaticArray, 2> digests; + digests.EmplaceBack("sha256:1234567890abcdef"); + digests.EmplaceBack("sha256:fedcba0987654321"); - EXPECT_EQ(promise.get_future().wait_for(std::chrono::seconds(1)), std::future_status::ready) - << "didn't receive connection status connected"; + StaticArray, 2> urls; - client->Unsubscribe(subscriber); + err = client->GetBlobsInfo(digests, urls); + ASSERT_TRUE(err.IsNone()) << "GetBlobsInfo failed"; - EXPECT_CALL(mLogProvider, Unsubscribe(_)).WillOnce(Return(Error())); + ASSERT_EQ(urls.Size(), 2); + EXPECT_EQ(urls[0], "http://example.com/blobs/sha256:1234567890abcdef"); + EXPECT_EQ(urls[1], "http://example.com/blobs/sha256:fedcba0987654321"); - auto err = client->Stop(); - ASSERT_TRUE(err.IsNone()) << "Can't stop client: error=" << err.Message(); + err = client->Stop(); + ASSERT_TRUE(err.IsNone()) << "Stop failed"; } From 47cab2e12347a3b27ade1533d7bf9e07fef9e549 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Wed, 10 Dec 2025 09:45:04 +0200 Subject: [PATCH 002/171] sm: smclient: update deps Signed-off-by: Mykola Solianko Reviewed-by: Mykola Kobets Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko --- src/sm/smclient/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/smclient/CMakeLists.txt b/src/sm/smclient/CMakeLists.txt index 686a1319f..165c23919 100644 --- a/src/sm/smclient/CMakeLists.txt +++ b/src/sm/smclient/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES smclient.cpp) # Libraries # ###################################################################################################################### -set(LIBRARIES aos::common::iamclient aos::common::pbconvert aos::common::utils aos::api::sm Poco::Util) +set(LIBRARIES aos::core::sm::smclient aos::common::pbconvert aos::common::iamclient) # ###################################################################################################################### # Target From 9e5a69479867a7ccb1fd1a334b8345b1994af374 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Wed, 10 Dec 2025 09:57:02 +0200 Subject: [PATCH 003/171] sm: cmake: make smclient build Signed-off-by: Mykola Solianko Reviewed-by: Mykola Kobets Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko --- src/sm/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/CMakeLists.txt b/src/sm/CMakeLists.txt index 2c1c52e61..a7af7e778 100644 --- a/src/sm/CMakeLists.txt +++ b/src/sm/CMakeLists.txt @@ -32,7 +32,7 @@ add_subdirectory(monitoring) # add_subdirectory(networkmanager) add_subdirectory(resourcemanager) # add_subdirectory(runner) -# add_subdirectory(smclient) +add_subdirectory(smclient) add_subdirectory(utils) # ###################################################################################################################### From 5b55c7661c28199e7d8c6abcec9c6e710730e937 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 12 Dec 2025 13:06:37 +0200 Subject: [PATCH 004/171] fixup! sm: tests: add UT --- src/sm/smclient/tests/smclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/smclient/tests/smclient.cpp b/src/sm/smclient/tests/smclient.cpp index 9d52aa8af..f4516fb8a 100644 --- a/src/sm/smclient/tests/smclient.cpp +++ b/src/sm/smclient/tests/smclient.cpp @@ -14,11 +14,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include From aae7c6c1df6d755b5ee5937f4743587bd0171906 Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 11 Dec 2025 10:50:31 +0200 Subject: [PATCH 005/171] cm: add database module Signed-off-by: Mykola Kobets Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykola Solianko --- src/cm/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cm/CMakeLists.txt b/src/cm/CMakeLists.txt index 5a8789974..60dd40528 100644 --- a/src/cm/CMakeLists.txt +++ b/src/cm/CMakeLists.txt @@ -24,7 +24,7 @@ set(TARGET_PREFIX ${TARGET_PREFIX}_cm) add_subdirectory(app) add_subdirectory(communication) add_subdirectory(config) -# add_subdirectory(database) +add_subdirectory(database) add_subdirectory(iamclient) add_subdirectory(networkmanager) add_subdirectory(smcontroller) From f29f1d10d76b6935377156f1c59fb831ceff971f Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 11 Dec 2025 10:53:19 +0200 Subject: [PATCH 006/171] cm: database: remove imagemanager::storage::StorageItf implementation Signed-off-by: Mykola Kobets Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykola Solianko --- src/cm/database/database.cpp | 282 ----------------------------- src/cm/database/database.hpp | 70 +------ src/cm/database/tests/database.cpp | 144 --------------- 3 files changed, 1 insertion(+), 495 deletions(-) diff --git a/src/cm/database/database.cpp b/src/cm/database/database.cpp index 4fe46d016..5dfc48e05 100644 --- a/src/cm/database/database.cpp +++ b/src/cm/database/database.cpp @@ -103,142 +103,6 @@ void DeserializeDNSServers(const std::string& jsonStr, Array("architecture").c_str())); - - if (src.has("variant")) { - dst.mArchInfo.mVariant.SetValue(src.getValue("variant").c_str()); - } - - AOS_ERROR_CHECK_AND_THROW(dst.mOSInfo.mOS.Assign(src.getValue("os").c_str())); - - if (src.has("osVersion")) { - dst.mOSInfo.mVersion.SetValue(src.getValue("osVersion").c_str()); - } - - if (src.has("features")) { - auto featuresArray = src.getArray("features"); - - for (const auto& featureJson : *featuresArray) { - AOS_ERROR_CHECK_AND_THROW( - dst.mOSInfo.mFeatures.PushBack(featureJson.convert().c_str()), "can't add feature"); - } - } -} - -void SerializeAosImageInfo(const aos::ImageInfo& src, Poco::JSON::Object& dst) -{ - dst.set("imageID", src.mImageID.CStr()); - SerializePlatformInfo(src, dst); -} - -void DeserializeAosImageInfo(const Poco::JSON::Object& src, aos::ImageInfo& dst) -{ - AOS_ERROR_CHECK_AND_THROW(dst.mImageID.Assign(src.getValue("imageID").c_str())); - DeserializePlatformInfo(src, dst); -} - -std::string SerializeImages(const Array& images) -{ - Poco::JSON::Array imagesJSON; - auto sha256Hex = std::make_unique>(); - - for (const auto& image : images) { - Poco::JSON::Object imageObj; - - imageObj.set("url", image.mURL.CStr()); - imageObj.set("path", image.mPath.CStr()); - imageObj.set("size", static_cast(image.mSize)); - - sha256Hex->Clear(); - AOS_ERROR_CHECK_AND_THROW(sha256Hex->ByteArrayToHex(image.mSHA256), "failed to convert SHA256 to hex"); - imageObj.set("sha256", sha256Hex->CStr()); - - Poco::JSON::Array metadataArray; - - for (const auto& metadata : image.mMetadata) { - metadataArray.add(metadata.CStr()); - } - - imageObj.set("metadata", metadataArray); - - SerializeAosImageInfo(image, imageObj); - - imagesJSON.add(imageObj); - } - - return common::utils::Stringify(imagesJSON); -} - -void DeserializeImages(const std::string& json, Array& images) -{ - Poco::JSON::Parser parser; - - auto imagesJSON = parser.parse(json).extract(); - if (imagesJSON == nullptr) { - AOS_ERROR_CHECK_AND_THROW(AOS_ERROR_WRAP(ErrorEnum::eFailed), "failed to parse images array"); - } - - auto imageInfo = std::make_unique(); - auto metadata = std::make_unique>(); - - images.Clear(); - - for (const auto& imageJson : *imagesJSON) { - const auto imageObj = imageJson.extract(); - if (imageObj == nullptr) { - AOS_ERROR_CHECK_AND_THROW(AOS_ERROR_WRAP(ErrorEnum::eFailed), "failed to parse image object"); - } - - imageInfo->mURL = imageObj->getValue("url").c_str(); - imageInfo->mPath = imageObj->getValue("path").c_str(); - imageInfo->mSize = imageObj->getValue("size"); - - auto sha256Hex = imageObj->getValue("sha256"); - AOS_ERROR_CHECK_AND_THROW( - String(sha256Hex.c_str()).HexToByteArray(imageInfo->mSHA256), "failed to convert hex to SHA256"); - - auto metadataArray = imageObj->getArray("metadata"); - if (metadataArray == nullptr) { - AOS_ERROR_CHECK_AND_THROW(AOS_ERROR_WRAP(ErrorEnum::eFailed), "failed to parse metadata array"); - } - - for (const auto& metadataJson : *metadataArray) { - AOS_ERROR_CHECK_AND_THROW( - metadata->Assign(metadataJson.convert().c_str()), "can't assign metadata"); - AOS_ERROR_CHECK_AND_THROW(imageInfo->mMetadata.PushBack(*metadata), "can't add metadata"); - } - - DeserializeAosImageInfo(*imageObj, *imageInfo); - - AOS_ERROR_CHECK_AND_THROW(images.PushBack(*imageInfo), "can't add image info"); - } -} - } // namespace /*********************************************************************************************************************** @@ -406,116 +270,6 @@ Error Database::UpdateStorageStateInfo(const storagestate::InstanceInfo& info) return ErrorEnum::eNone; } -/*********************************************************************************************************************** - * imagemanager::storage::StorageItf implementation - **********************************************************************************************************************/ - -Error Database::SetItemState(const String& id, const String& version, imagemanager::storage::ItemState state) -{ - std::lock_guard lock {mMutex}; - - try { - Poco::Data::Statement statement {*mSession}; - - statement << "UPDATE imagemanager SET state = ? WHERE id = ? AND version = ?;", bind(state.ToString().CStr()), - bind(id.CStr()), bind(version.CStr()); - - if (statement.execute() != 1) { - return ErrorEnum::eNotFound; - } - } catch (const std::exception& e) { - return AOS_ERROR_WRAP(common::utils::ToAosError(e)); - } - - return ErrorEnum::eNone; -} - -Error Database::RemoveItem(const String& id, const String& version) -{ - std::lock_guard lock {mMutex}; - - try { - Poco::Data::Statement statement {*mSession}; - - statement << "DELETE FROM imagemanager WHERE id = ? AND version = ?;", bind(id.CStr()), bind(version.CStr()); - - if (statement.execute() != 1) { - return ErrorEnum::eNotFound; - } - } catch (const std::exception& e) { - return AOS_ERROR_WRAP(common::utils::ToAosError(e)); - } - - return ErrorEnum::eNone; -} - -Error Database::GetItemsInfo(Array& items) -{ - std::lock_guard lock {mMutex}; - - try { - std::vector rows; - - *mSession << "SELECT id, type, version, state, path, totalSize, gid, timestamp, images FROM imagemanager;", - into(rows), now; - - auto itemInfo = std::make_unique(); - items.Clear(); - - for (const auto& row : rows) { - ToAos(row, *itemInfo); - AOS_ERROR_CHECK_AND_THROW(items.PushBack(*itemInfo), "can't add item info"); - } - } catch (const std::exception& e) { - return AOS_ERROR_WRAP(common::utils::ToAosError(e)); - } - - return ErrorEnum::eNone; -} - -Error Database::GetItemVersionsByID(const String& id, Array& items) -{ - std::lock_guard lock {mMutex}; - - try { - std::vector rows; - - *mSession << "SELECT id, type, version, state, path, totalSize, gid, timestamp, images FROM imagemanager WHERE " - "id = ?;", - bind(id.CStr()), into(rows), now; - - auto itemInfo = std::make_unique(); - items.Clear(); - - for (const auto& row : rows) { - ToAos(row, *itemInfo); - AOS_ERROR_CHECK_AND_THROW(items.PushBack(*itemInfo), "can't add item info"); - } - } catch (const std::exception& e) { - return AOS_ERROR_WRAP(common::utils::ToAosError(e)); - } - - return ErrorEnum::eNone; -} - -Error Database::AddItem(const imagemanager::storage::ItemInfo& item) -{ - std::lock_guard lock {mMutex}; - - try { - ImageManagerItemInfoRow row; - - FromAos(item, row); - *mSession << "INSERT INTO imagemanager (id, type, version, state, path, totalSize, gid, timestamp, images) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", - bind(row), now; - } catch (const std::exception& e) { - return AOS_ERROR_WRAP(common::utils::ToAosError(e)); - } - - return ErrorEnum::eNone; -} - /*********************************************************************************************************************** * networkmanager::StorageItf implementation **********************************************************************************************************************/ @@ -941,42 +695,6 @@ void Database::ToAos(const StorageStateInstanceInfoRow& src, storagestate::Insta AOS_ERROR_CHECK_AND_THROW(dst.mStateChecksum.Assign(Array(blob.rawContent(), blob.size()))); } -void Database::FromAos(const imagemanager::storage::ItemInfo& src, ImageManagerItemInfoRow& dst) -{ - dst.set(src.mID.CStr()); - dst.set(src.mType.ToString().CStr()); - dst.set(src.mVersion.CStr()); - dst.set(src.mState.ToString().CStr()); - dst.set(src.mPath.CStr()); - dst.set(src.mTotalSize); - dst.set(src.mGID); - dst.set(src.mTimestamp.UnixNano()); - dst.set(SerializeImages(src.mImages)); -} - -void Database::ToAos(const ImageManagerItemInfoRow& src, imagemanager::storage::ItemInfo& dst) -{ - dst.mID = src.get().c_str(); - dst.mVersion = src.get().c_str(); - dst.mPath = src.get().c_str(); - dst.mTotalSize = src.get(); - dst.mGID = src.get(); - dst.mTimestamp - = Time::Unix(src.get() / Time::cSeconds.Nanoseconds(), - src.get() % Time::cSeconds.Nanoseconds()); - - if (auto err = dst.mType.FromString(src.get().c_str()); !err.IsNone()) { - AOS_ERROR_CHECK_AND_THROW(err, "failed to parse item type"); - } - - if (auto err = dst.mState.FromString(src.get().c_str()); - !err.IsNone()) { - AOS_ERROR_CHECK_AND_THROW(err, "failed to parse item state"); - } - - DeserializeImages(src.get(), dst.mImages); -} - void Database::FromAos(const networkmanager::Network& src, NetworkManagerNetworkRow& dst) { dst.set(src.mNetworkID.CStr()); diff --git a/src/cm/database/database.hpp b/src/cm/database/database.hpp index e7431294a..6130c8214 100644 --- a/src/cm/database/database.hpp +++ b/src/cm/database/database.hpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -29,10 +28,7 @@ namespace aos::cm::database { /** * Database class. */ -class Database : public storagestate::StorageItf, - public imagemanager::storage::StorageItf, - public networkmanager::StorageItf, - public launcher::StorageItf { +class Database : public storagestate::StorageItf, public networkmanager::StorageItf, public launcher::StorageItf { public: /** * Creates database instance. @@ -97,54 +93,6 @@ class Database : public storagestate::StorageItf, */ Error UpdateStorageStateInfo(const storagestate::InstanceInfo& info) override; - // - // imagemanager::storage::StorageItf interface - // - - /** - * Sets item state. - * - * @param id ID. - * @param version Version. - * @param state Item state. - * @return Error. - */ - Error SetItemState(const String& id, const String& version, imagemanager::storage::ItemState state) override; - - /** - * Removes item. - * - * @param id ID. - * @param version Version. - * @return Error. - */ - Error RemoveItem(const String& id, const String& version) override; - - /** - * Gets items info. - * - * @param items Items info. - * @return Error. - */ - Error GetItemsInfo(Array& items) override; - - /** - * Gets item versions by ID. - * - * @param id ID. - * @param items Items info. - * @return Error. - */ - Error GetItemVersionsByID(const String& id, Array& items) override; - - /** - * Adds item. - * - * @param item Item info. - * @return Error. - */ - Error AddItem(const imagemanager::storage::ItemInfo& item) override; - // // networkmanager::StorageItf interface // @@ -287,20 +235,6 @@ class Database : public storagestate::StorageItf, using StorageStateInstanceInfoRow = Poco::Tuple; - enum class ImageManagerItemInfoColumns : int { - eID = 0, - eType, - eVersion, - eState, - ePath, - eTotalSize, - eGID, - eTimestamp, - eImages - }; - using ImageManagerItemInfoRow = Poco::Tuple; - enum class NetworkManagerNetworkColumns : int { eNetworkID = 0, eSubnet, eVlanID }; using NetworkManagerNetworkRow = Poco::Tuple; @@ -343,8 +277,6 @@ class Database : public storagestate::StorageItf, static void FromAos(const storagestate::InstanceInfo& src, StorageStateInstanceInfoRow& dst); static void ToAos(const StorageStateInstanceInfoRow& src, storagestate::InstanceInfo& dst); - static void FromAos(const imagemanager::storage::ItemInfo& src, ImageManagerItemInfoRow& dst); - static void ToAos(const ImageManagerItemInfoRow& src, imagemanager::storage::ItemInfo& dst); static void FromAos(const networkmanager::Network& src, NetworkManagerNetworkRow& dst); static void ToAos(const NetworkManagerNetworkRow& src, networkmanager::Network& dst); diff --git a/src/cm/database/tests/database.cpp b/src/cm/database/tests/database.cpp index 6cf897904..ea2fea448 100644 --- a/src/cm/database/tests/database.cpp +++ b/src/cm/database/tests/database.cpp @@ -50,44 +50,6 @@ storagestate::InstanceInfo CreateStorageStateInstanceInfo( return info; } -imagemanager::storage::ItemInfo CreateImageManagerItemInfo( - const char* id, const char* version, imagemanager::storage::ItemStateEnum state, size_t totalSize) -{ - imagemanager::storage::ItemInfo item; - - item.mID = id; - item.mVersion = version; - item.mTotalSize = totalSize; - item.mGID = 1000; - item.mPath = "/path/to/item"; - item.mTimestamp = Time::Now(); - - item.mType = UpdateItemTypeEnum::eComponent; - item.mState = state; - - // Add a sample image - imagemanager::storage::ImageInfo imageInfo; - imageInfo.mURL = "http://example.com/image.tar"; - imageInfo.mPath = "/path/to/image"; - imageInfo.mSize = 1024 * 1024; - - // SHA256 hash (magic number) - static const std::vector cSHA256MagicNumber = {0xde, 0xad, 0xbe, 0xef}; - - imageInfo.mSHA256 = Array(cSHA256MagicNumber.data(), cSHA256MagicNumber.size()); - - // Platform info - imageInfo.mImageID = "image1"; - imageInfo.mArchInfo.mArchitecture = "amd64"; - imageInfo.mArchInfo.mVariant.SetValue("v8"); - imageInfo.mOSInfo.mOS = "linux"; - imageInfo.mOSInfo.mVersion.SetValue("5.10"); - - AOS_ERROR_CHECK_AND_THROW(item.mImages.PushBack(imageInfo), "can't add image"); - - return item; -} - networkmanager::Network CreateNetwork(const char* networkID, const char* subnet, uint64_t vlanID) { networkmanager::Network network; @@ -315,112 +277,6 @@ TEST_F(CMDatabaseTest, StateStorageUpdateStorageStateInfo) ASSERT_FALSE(mDB.UpdateStorageStateInfo(nonExistentInfo).IsNone()); } -/*********************************************************************************************************************** - * imagemanager::storage::StorageItf tests - **********************************************************************************************************************/ - -TEST_F(CMDatabaseTest, ImageManagerAddItem) -{ - ASSERT_TRUE(mDB.Init(mDatabaseConfig).IsNone()); - - auto item - = CreateImageManagerItemInfo("item1", "1.0.0", imagemanager::storage::ItemStateEnum::eCached, 1024 * 1024); - - ASSERT_TRUE(mDB.AddItem(item).IsNone()); - - // Verify the item was added by retrieving all items - StaticArray allItems; - ASSERT_TRUE(mDB.GetItemsInfo(allItems).IsNone()); - EXPECT_THAT(ToVector(allItems), UnorderedElementsAre(item)); -} - -TEST_F(CMDatabaseTest, ImageManagerSetItemState) -{ - ASSERT_TRUE(mDB.Init(mDatabaseConfig).IsNone()); - - // Set state for non-existent item - auto err = mDB.SetItemState( - "nonexistent", "1.0.0", imagemanager::storage::ItemState(imagemanager::storage::ItemStateEnum::eActive)); - ASSERT_EQ(err, ErrorEnum::eNotFound); - - // Add an item with state "cached" - auto item - = CreateImageManagerItemInfo("item1", "1.0.0", imagemanager::storage::ItemStateEnum::eCached, 1024 * 1024); - ASSERT_TRUE(mDB.AddItem(item).IsNone()); - - StaticArray allItems; - ASSERT_TRUE(mDB.GetItemsInfo(allItems).IsNone()); - ASSERT_EQ(allItems.Size(), 1); - EXPECT_EQ(allItems[0].mState, imagemanager::storage::ItemStateEnum::eCached); - - // Set state to "active" - ASSERT_TRUE(mDB.SetItemState(item.mID, item.mVersion, imagemanager::storage::ItemStateEnum::eActive).IsNone()); - - ASSERT_TRUE(mDB.GetItemsInfo(allItems).IsNone()); - ASSERT_EQ(allItems.Size(), 1); - EXPECT_EQ(allItems[0].mState, imagemanager::storage::ItemStateEnum::eActive); -} - -TEST_F(CMDatabaseTest, ImageManagerRemoveItem) -{ - ASSERT_TRUE(mDB.Init(mDatabaseConfig).IsNone()); - - // Remove non-existent item - EXPECT_EQ(mDB.RemoveItem("nonexistent", "1.0.0"), ErrorEnum::eNotFound); - - // Add items - auto item1 - = CreateImageManagerItemInfo("item1", "1.0.0", imagemanager::storage::ItemStateEnum::eCached, 1024 * 1024); - auto item2 - = CreateImageManagerItemInfo("item2", "2.0.0", imagemanager::storage::ItemStateEnum::eActive, 2048 * 1024); - - ASSERT_TRUE(mDB.AddItem(item1).IsNone()); - ASSERT_TRUE(mDB.AddItem(item2).IsNone()); - - // Remove item2 - ASSERT_TRUE(mDB.RemoveItem(item2.mID, item2.mVersion).IsNone()); - - StaticArray allItems; - ASSERT_TRUE(mDB.GetItemsInfo(allItems).IsNone()); - EXPECT_THAT(ToVector(allItems), UnorderedElementsAre(item1)); - - // Remove item2 again - EXPECT_EQ(mDB.RemoveItem(item2.mID, item2.mVersion), ErrorEnum::eNotFound); -} - -TEST_F(CMDatabaseTest, ImageManagerGetItemVersionsByID) -{ - ASSERT_TRUE(mDB.Init(mDatabaseConfig).IsNone()); - - // Get versions for non-existent item - should return empty - StaticArray versions; - ASSERT_TRUE(mDB.GetItemVersionsByID("nonexistent", versions).IsNone()); - EXPECT_EQ(versions.Size(), 0); - - // Add items - auto item1v1 - = CreateImageManagerItemInfo("item1", "1.0.0", imagemanager::storage::ItemStateEnum::eCached, 1024 * 1024); - auto item1v2 - = CreateImageManagerItemInfo("item1", "2.0.0", imagemanager::storage::ItemStateEnum::eActive, 2048 * 1024); - auto item1v3 - = CreateImageManagerItemInfo("item1", "3.0.0", imagemanager::storage::ItemStateEnum::eCached, 3072 * 1024); - auto item2v1 - = CreateImageManagerItemInfo("item2", "1.0.0", imagemanager::storage::ItemStateEnum::eActive, 512 * 1024); - - ASSERT_TRUE(mDB.AddItem(item1v1).IsNone()); - ASSERT_TRUE(mDB.AddItem(item1v2).IsNone()); - ASSERT_TRUE(mDB.AddItem(item1v3).IsNone()); - ASSERT_TRUE(mDB.AddItem(item2v1).IsNone()); - - // Get all versions of item1 - ASSERT_TRUE(mDB.GetItemVersionsByID("item1", versions).IsNone()); - EXPECT_THAT(ToVector(versions), UnorderedElementsAre(item1v1, item1v2, item1v3)); - - // Get all versions of item2 - ASSERT_TRUE(mDB.GetItemVersionsByID("item2", versions).IsNone()); - EXPECT_THAT(ToVector(versions), UnorderedElementsAre(item2v1)); -} - /*********************************************************************************************************************** * networkmanager::StorageItf tests **********************************************************************************************************************/ From 936a8fbb7bf06e11e83718ceb1c26ce1d9eae16d Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 11 Dec 2025 11:00:32 +0200 Subject: [PATCH 007/171] cm: database: add InstanceIdent::mType to database Signed-off-by: Mykola Kobets Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykola Solianko --- src/cm/database/database.cpp | 53 +++++++++++++++++++----------- src/cm/database/database.hpp | 6 ++-- src/cm/database/tests/database.cpp | 11 ++++--- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/cm/database/database.cpp b/src/cm/database/database.cpp index 5dfc48e05..c4f200277 100644 --- a/src/cm/database/database.cpp +++ b/src/cm/database/database.cpp @@ -167,8 +167,8 @@ Error Database::AddStorageStateInfo(const storagestate::InstanceInfo& info) StorageStateInstanceInfoRow row; FromAos(info, row); - *mSession << "INSERT INTO storagestate (itemID, subjectID, instance, storageQuota, " - "stateQuota, stateChecksum) VALUES (?, ?, ?, ?, ?, ?);", + *mSession << "INSERT INTO storagestate (itemID, subjectID, instance, type, storageQuota, " + "stateQuota, stateChecksum) VALUES (?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -184,8 +184,9 @@ Error Database::RemoveStorageStateInfo(const InstanceIdent& instanceIdent) try { Poco::Data::Statement statement {*mSession}; - statement << "DELETE FROM storagestate WHERE itemID = ? AND subjectID = ? AND instance = ?;", - bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance); + statement << "DELETE FROM storagestate WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), + bind(instanceIdent.mType.ToString().CStr()); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -203,7 +204,7 @@ Error Database::GetAllStorageStateInfo(Array& info) try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, storageQuota, stateQuota, stateChecksum FROM " + *mSession << "SELECT itemID, subjectID, instance, type, storageQuota, stateQuota, stateChecksum FROM " "storagestate;", into(rows), now; @@ -229,10 +230,10 @@ Error Database::GetStorageStateInfo(const InstanceIdent& instanceIdent, storages StorageStateInstanceInfoRow row; Poco::Data::Statement statement {*mSession}; - statement << "SELECT itemID, subjectID, instance, storageQuota, stateQuota, stateChecksum FROM " - "storagestate WHERE itemID = ? AND subjectID = ? AND instance = ?;", + statement << "SELECT itemID, subjectID, instance, type, storageQuota, stateQuota, stateChecksum FROM " + "storagestate WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), - into(row); + bind(instanceIdent.mType.ToString().CStr()), into(row); if (statement.execute() == 0) { return ErrorEnum::eNotFound; @@ -255,10 +256,10 @@ Error Database::UpdateStorageStateInfo(const storagestate::InstanceInfo& info) Poco::Data::BLOB checksumBlob(info.mStateChecksum.begin(), info.mStateChecksum.Size()); statement << "UPDATE storagestate SET storageQuota = ?, stateQuota = ?, stateChecksum = ? WHERE " - "itemID = ? AND subjectID = ? AND instance = ?;", + "itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", bind(info.mStorageQuota), bind(info.mStateQuota), bind(checksumBlob), bind(info.mInstanceIdent.mItemID.CStr()), bind(info.mInstanceIdent.mSubjectID.CStr()), - bind(info.mInstanceIdent.mInstance); + bind(info.mInstanceIdent.mInstance), bind(info.mInstanceIdent.mType.ToString().CStr()); if (statement.execute() == 0) { return ErrorEnum::eNotFound; @@ -314,8 +315,8 @@ Error Database::AddInstance(const networkmanager::Instance& instance) NetworkManagerInstanceRow row; FromAos(instance, row); - *mSession << "INSERT INTO networkmanager_instances (itemID, subjectID, instance, networkID, nodeID, ip, " - "exposedPorts, dnsServers) VALUES (?, ?, ?, ?, ?, ?, ?, ?);", + *mSession << "INSERT INTO networkmanager_instances (itemID, subjectID, instance, type, networkID, nodeID, ip, " + "exposedPorts, dnsServers) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -380,7 +381,7 @@ Error Database::GetInstances(const String& networkID, const String& nodeID, Arra try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, networkID, nodeID, ip, exposedPorts, dnsServers FROM " + *mSession << "SELECT itemID, subjectID, instance, type, networkID, nodeID, ip, exposedPorts, dnsServers FROM " "networkmanager_instances WHERE networkID = ? AND nodeID = ?;", bind(networkID.CStr()), bind(nodeID.CStr()), into(rows), now; @@ -445,8 +446,10 @@ Error Database::RemoveNetworkInstance(const InstanceIdent& instanceIdent) try { Poco::Data::Statement statement {*mSession}; - statement << "DELETE FROM networkmanager_instances WHERE itemID = ? AND subjectID = ? AND instance = ?;", - bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance); + statement + << "DELETE FROM networkmanager_instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), + bind(instanceIdent.mType.ToString().CStr()); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -587,10 +590,11 @@ void Database::CreateTables() "itemID TEXT," "subjectID TEXT," "instance INTEGER," + "type TEXT," "storageQuota INTEGER," "stateQuota INTEGER," "stateChecksum BLOB," - "PRIMARY KEY(itemID,subjectID,instance)" + "PRIMARY KEY(itemID,subjectID,instance,type)" ");", now; @@ -637,12 +641,13 @@ void Database::CreateTables() "itemID TEXT," "subjectID TEXT," "instance INTEGER," + "type TEXT," "networkID TEXT," "nodeID TEXT," "ip TEXT," "exposedPorts TEXT," "dnsServers TEXT," - "PRIMARY KEY(itemID,subjectID,instance)," + "PRIMARY KEY(itemID,subjectID,instance,type)," "FOREIGN KEY(networkID) REFERENCES networks(networkID)," "FOREIGN KEY(networkID,nodeID) REFERENCES hosts(networkID,nodeID)" ");", @@ -677,6 +682,7 @@ void Database::FromAos(const storagestate::InstanceInfo& src, StorageStateInstan dst.set(src.mInstanceIdent.mItemID.CStr()); dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); + dst.set(src.mInstanceIdent.mType.ToString().CStr()); dst.set(src.mStorageQuota); dst.set(src.mStateQuota); dst.set( @@ -692,6 +698,9 @@ void Database::ToAos(const StorageStateInstanceInfoRow& src, storagestate::Insta dst.mInstanceIdent.mInstance = src.get(); dst.mStorageQuota = src.get(); dst.mStateQuota = src.get(); + AOS_ERROR_CHECK_AND_THROW( + dst.mInstanceIdent.mType.FromString(src.get().c_str()), + "failed to parse instance type"); AOS_ERROR_CHECK_AND_THROW(dst.mStateChecksum.Assign(Array(blob.rawContent(), blob.size()))); } @@ -727,6 +736,7 @@ void Database::FromAos(const networkmanager::Instance& src, NetworkManagerInstan dst.set(src.mInstanceIdent.mItemID.CStr()); dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); + dst.set(src.mInstanceIdent.mType.ToString().CStr()); dst.set(src.mNetworkID.CStr()); dst.set(src.mNodeID.CStr()); dst.set(src.mIP.CStr()); @@ -739,9 +749,12 @@ void Database::ToAos(const NetworkManagerInstanceRow& src, networkmanager::Insta dst.mInstanceIdent.mItemID = src.get().c_str(); dst.mInstanceIdent.mSubjectID = src.get().c_str(); dst.mInstanceIdent.mInstance = src.get(); - dst.mNetworkID = src.get().c_str(); - dst.mNodeID = src.get().c_str(); - dst.mIP = src.get().c_str(); + AOS_ERROR_CHECK_AND_THROW( + dst.mInstanceIdent.mType.FromString(src.get().c_str()), + "failed to parse instance type"); + dst.mNetworkID = src.get().c_str(); + dst.mNodeID = src.get().c_str(); + dst.mIP = src.get().c_str(); DeserializeExposedPorts(src.get(), dst.mExposedPorts); DeserializeDNSServers(src.get(), dst.mDNSServers); diff --git a/src/cm/database/database.hpp b/src/cm/database/database.hpp index 6130c8214..a02f90db1 100644 --- a/src/cm/database/database.hpp +++ b/src/cm/database/database.hpp @@ -228,12 +228,13 @@ class Database : public storagestate::StorageItf, public networkmanager::Storage eItemID = 0, eSubjectID, eInstance, + eType, eStorageQuota, eStateQuota, eStateChecksum }; using StorageStateInstanceInfoRow - = Poco::Tuple; + = Poco::Tuple; enum class NetworkManagerNetworkColumns : int { eNetworkID = 0, eSubnet, eVlanID }; using NetworkManagerNetworkRow = Poco::Tuple; @@ -245,6 +246,7 @@ class Database : public storagestate::StorageItf, public networkmanager::Storage eItemID = 0, eSubjectID, eInstance, + eType, eNetworkID, eNodeID, eIP, @@ -252,7 +254,7 @@ class Database : public storagestate::StorageItf, public networkmanager::Storage eDNSServers }; using NetworkManagerInstanceRow = Poco::Tuple; + std::string, std::string, std::string, std::string>; enum class LauncherInstanceInfoColumns : int { eItemID = 0, diff --git a/src/cm/database/tests/database.cpp b/src/cm/database/tests/database.cpp index ea2fea448..001582fe6 100644 --- a/src/cm/database/tests/database.cpp +++ b/src/cm/database/tests/database.cpp @@ -25,13 +25,15 @@ std::vector ToVector(const Array& src) return std::vector(src.begin(), src.end()); } -InstanceIdent CreateInstanceIdent(const char* itemID, const char* subjectID, uint64_t instance) +InstanceIdent CreateInstanceIdent(const char* itemID, const char* subjectID, uint64_t instance, + UpdateItemType itemType = UpdateItemTypeEnum::eService) { InstanceIdent ident; ident.mItemID = itemID; ident.mSubjectID = subjectID; ident.mInstance = instance; + ident.mType = itemType; return ident; } @@ -72,11 +74,11 @@ networkmanager::Host CreateHost(const char* nodeID, const char* ip) } networkmanager::Instance CreateInstance(const char* itemID, const char* subjectID, uint64_t instance, - const char* networkID, const char* nodeID, const char* ip) + const char* networkID, const char* nodeID, const char* ip, UpdateItemType itemType = UpdateItemTypeEnum::eService) { networkmanager::Instance inst; - inst.mInstanceIdent = CreateInstanceIdent(itemID, subjectID, instance); + inst.mInstanceIdent = CreateInstanceIdent(itemID, subjectID, instance, itemType); inst.mNetworkID = networkID; inst.mNodeID = nodeID; inst.mIP = ip; @@ -349,7 +351,8 @@ TEST_F(CMDatabaseTest, NetworkManagerAddInstance) auto instance1 = CreateInstance("service1", "subject1", 0, "network1", "node1", "172.17.0.10"); auto instance2 = CreateInstance("service1", "subject1", 1, "network1", "node1", "172.17.0.11"); - auto instance3 = CreateInstance("service2", "subject2", 0, "network1", "node1", "172.17.0.12"); + auto instance3 + = CreateInstance("service2", "subject2", 0, "network1", "node1", "172.17.0.12", UpdateItemTypeEnum::eComponent); // Add instances ASSERT_TRUE(mDB.AddInstance(instance1).IsNone()); From 41d5342efe3d6c550e6274685374b5089f762b61 Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 11 Dec 2025 11:05:33 +0200 Subject: [PATCH 008/171] cm: database: update launcher:StorageItf implementation Signed-off-by: Mykola Kobets Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykola Solianko --- src/cm/database/database.cpp | 72 ++++++++++++++++-------------- src/cm/database/database.hpp | 8 ++-- src/cm/database/tests/database.cpp | 25 ++++++----- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/cm/database/database.cpp b/src/cm/database/database.cpp index c4f200277..6efd4c786 100644 --- a/src/cm/database/database.cpp +++ b/src/cm/database/database.cpp @@ -473,8 +473,9 @@ Error Database::AddInstance(const launcher::InstanceInfo& info) LauncherInstanceInfoRow row; FromAos(info, row); - *mSession << "INSERT INTO launcher_instances (itemID, subjectID, instance, imageID, updateItemType, nodeID, " - "prevNodeID, runtimeID, uid, timestamp, cached) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + *mSession << "INSERT INTO launcher_instances (itemID, subjectID, instance, type, manifestDigest, " + "nodeID, prevNodeID, runtimeID, uid, gid, timestamp, cached) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -490,13 +491,13 @@ Error Database::UpdateInstance(const launcher::InstanceInfo& info) try { Poco::Data::Statement statement {*mSession}; - statement - << "UPDATE launcher_instances SET imageID = ?, updateItemType = ?, nodeID = ?, prevNodeID = ?, " - "runtimeID = ?, uid = ?, timestamp = ?, cached = ? WHERE itemID = ? AND subjectID = ? AND instance = ?;", - bind(info.mImageID.CStr()), bind(info.mUpdateItemType.ToString().CStr()), bind(info.mNodeID.CStr()), - bind(info.mPrevNodeID.CStr()), bind(info.mRuntimeID.CStr()), bind(info.mUID), - bind(info.mTimestamp.UnixNano()), bind(info.mCached), bind(info.mInstanceIdent.mItemID.CStr()), - bind(info.mInstanceIdent.mSubjectID.CStr()), bind(info.mInstanceIdent.mInstance); + statement << "UPDATE launcher_instances SET manifestDigest = ?, nodeID = ?, prevNodeID = " + "?, runtimeID = ?, uid = ?, gid = ?, timestamp = ?, cached = ? WHERE itemID = ? AND subjectID = ? " + "AND instance = ? AND type = ?;", + bind(info.mManifestDigest.CStr()), bind(info.mNodeID.CStr()), bind(info.mPrevNodeID.CStr()), + bind(info.mRuntimeID.CStr()), bind(info.mUID), bind(info.mGID), bind(info.mTimestamp.UnixNano()), + bind(info.mCached), bind(info.mInstanceIdent.mItemID.CStr()), bind(info.mInstanceIdent.mSubjectID.CStr()), + bind(info.mInstanceIdent.mInstance), bind(info.mInstanceIdent.mType.ToString().CStr()); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -515,10 +516,11 @@ Error Database::GetInstance(const InstanceIdent& instanceID, launcher::InstanceI try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, imageID, updateItemType, nodeID, prevNodeID, runtimeID, uid, " - "timestamp, cached FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ?;", - bind(instanceID.mItemID.CStr()), bind(instanceID.mSubjectID.CStr()), bind(instanceID.mInstance), into(rows), - now; + *mSession << "SELECT itemID, subjectID, instance, type, manifestDigest, nodeID, prevNodeID, " + "runtimeID, uid, gid, timestamp, cached FROM launcher_instances WHERE itemID = ? AND subjectID = " + "? AND instance = ? AND type = ?;", + bind(instanceID.mItemID.CStr()), bind(instanceID.mSubjectID.CStr()), bind(instanceID.mInstance), + bind(instanceID.mType.ToString().CStr()), into(rows), now; if (rows.size() != 1) { return ErrorEnum::eNotFound; @@ -539,8 +541,8 @@ Error Database::GetActiveInstances(Array& instances) con try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, imageID, updateItemType, nodeID, prevNodeID, runtimeID, uid, " - "timestamp, cached FROM launcher_instances;", + *mSession << "SELECT itemID, subjectID, instance, type, manifestDigest, nodeID, prevNodeID, " + "runtimeID, uid, gid, timestamp, cached FROM launcher_instances;", into(rows), now; auto instanceInfo = std::make_unique(); @@ -565,8 +567,9 @@ Error Database::RemoveInstance(const InstanceIdent& instanceIdent) Poco::Data::Statement statement {*mSession}; statement.reset(*mSession); - statement << "DELETE FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ?;", - bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance); + statement << "DELETE FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), + bind(instanceIdent.mType.ToString().CStr()); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -659,15 +662,16 @@ void Database::CreateTables() "itemID TEXT," "subjectID TEXT," "instance INTEGER," - "imageID TEXT," - "updateItemType TEXT," + "type TEXT," + "manifestDigest TEXT," "nodeID TEXT," "prevNodeID TEXT," "runtimeID TEXT," "uid INTEGER," + "gid INTEGER," "timestamp INTEGER," "cached INTEGER," - "PRIMARY KEY(itemID,subjectID,instance)" + "PRIMARY KEY(itemID,subjectID,instance,type)" ");", now; } @@ -765,34 +769,36 @@ void Database::FromAos(const launcher::InstanceInfo& src, LauncherInstanceInfoRo dst.set(src.mInstanceIdent.mItemID.CStr()); dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); - dst.set(src.mImageID.CStr()); - dst.set(src.mUpdateItemType.ToString().CStr()); + dst.set(src.mInstanceIdent.mType.ToString().CStr()); + dst.set(src.mManifestDigest.CStr()); dst.set(src.mNodeID.CStr()); dst.set(src.mPrevNodeID.CStr()); dst.set(src.mRuntimeID.CStr()); dst.set(src.mUID); + dst.set(src.mGID); dst.set(src.mTimestamp.UnixNano()); dst.set(src.mCached); } void Database::ToAos(const LauncherInstanceInfoRow& src, launcher::InstanceInfo& dst) { - auto timestamp = src.get(); - auto updateItemType = src.get(); - dst.mInstanceIdent.mItemID = src.get().c_str(); dst.mInstanceIdent.mSubjectID = src.get().c_str(); dst.mInstanceIdent.mInstance = src.get(); - dst.mImageID = src.get().c_str(); - dst.mNodeID = src.get().c_str(); - dst.mPrevNodeID = src.get().c_str(); - dst.mRuntimeID = src.get().c_str(); - dst.mUID = src.get(); + AOS_ERROR_CHECK_AND_THROW( + dst.mInstanceIdent.mType.FromString(src.get().c_str()), + "failed to parse instance type"); + dst.mManifestDigest = src.get().c_str(); + dst.mNodeID = src.get().c_str(); + dst.mPrevNodeID = src.get().c_str(); + dst.mRuntimeID = src.get().c_str(); + dst.mUID = src.get(); + dst.mGID = src.get(); + + auto timestamp = src.get(); dst.mTimestamp = Time::Unix(timestamp / Time::cSeconds.Nanoseconds(), timestamp % Time::cSeconds.Nanoseconds()); - dst.mCached = src.get(); - AOS_ERROR_CHECK_AND_THROW( - dst.mUpdateItemType.FromString(updateItemType.c_str()), "failed to parse update item type"); + dst.mCached = src.get(); } } // namespace aos::cm::database diff --git a/src/cm/database/database.hpp b/src/cm/database/database.hpp index a02f90db1..b67b01ece 100644 --- a/src/cm/database/database.hpp +++ b/src/cm/database/database.hpp @@ -260,17 +260,18 @@ class Database : public storagestate::StorageItf, public networkmanager::Storage eItemID = 0, eSubjectID, eInstance, - eImageID, - eUpdateItemType, + eType, + eManifestDigest, eNodeID, ePrevNodeID, eRuntimeID, eUID, + eGID, eTimestamp, eCached }; using LauncherInstanceInfoRow = Poco::Tuple; + std::string, std::string, std::string, uint32_t, uint32_t, uint64_t, bool>; // make virtual for unit tests virtual int GetVersion() const; @@ -279,7 +280,6 @@ class Database : public storagestate::StorageItf, public networkmanager::Storage static void FromAos(const storagestate::InstanceInfo& src, StorageStateInstanceInfoRow& dst); static void ToAos(const StorageStateInstanceInfoRow& src, storagestate::InstanceInfo& dst); - static void FromAos(const networkmanager::Network& src, NetworkManagerNetworkRow& dst); static void ToAos(const NetworkManagerNetworkRow& src, networkmanager::Network& dst); diff --git a/src/cm/database/tests/database.cpp b/src/cm/database/tests/database.cpp index 001582fe6..ac103d1b0 100644 --- a/src/cm/database/tests/database.cpp +++ b/src/cm/database/tests/database.cpp @@ -101,18 +101,18 @@ networkmanager::Instance CreateInstance(const char* itemID, const char* subjectI return inst; } -launcher::InstanceInfo CreateLauncherInstanceInfo( - const char* itemID, const char* subjectID, uint64_t instance, const char* imageID, const char* nodeID) +launcher::InstanceInfo CreateLauncherInstanceInfo(const char* itemID, const char* subjectID, uint64_t instance, + const char* manifestDigest, const char* nodeID, UpdateItemType itemType = UpdateItemTypeEnum::eService) { launcher::InstanceInfo info; - info.mInstanceIdent = CreateInstanceIdent(itemID, subjectID, instance); - info.mImageID = imageID; - info.mUpdateItemType = UpdateItemTypeEnum::eService; + info.mInstanceIdent = CreateInstanceIdent(itemID, subjectID, instance, itemType); + info.mManifestDigest = manifestDigest; info.mNodeID = nodeID; info.mPrevNodeID = "prevNode"; info.mRuntimeID = "runc"; info.mUID = 1000; + info.mGID = 2000; info.mTimestamp = Time::Now(); info.mCached = true; @@ -482,7 +482,8 @@ TEST_F(CMDatabaseTest, LauncherAddInstance) auto instance1 = CreateLauncherInstanceInfo("service1", "subject1", 0, "image1", "node1"); auto instance2 = CreateLauncherInstanceInfo("service1", "subject1", 1, "image1", "node1"); - auto instance3 = CreateLauncherInstanceInfo("service2", "subject2", 0, "image2", "node2"); + auto instance3 + = CreateLauncherInstanceInfo("service2", "subject2", 0, "image2", "node2", UpdateItemTypeEnum::eComponent); // Add instances ASSERT_TRUE(mDB.AddInstance(instance1).IsNone()); @@ -512,12 +513,12 @@ TEST_F(CMDatabaseTest, LauncherUpdateInstance) ASSERT_TRUE(mDB.AddInstance(instance2).IsNone()); // Update instance - instance1.mImageID = "image1-updated"; - instance1.mNodeID = "node1-updated"; - instance1.mPrevNodeID = "node1"; - instance1.mRuntimeID = "crun"; - instance1.mUID = 2000; - instance1.mCached = false; + instance1.mManifestDigest = "image1-updated"; + instance1.mNodeID = "node1-updated"; + instance1.mPrevNodeID = "node1"; + instance1.mRuntimeID = "crun"; + instance1.mUID = 2000; + instance1.mCached = false; ASSERT_TRUE(mDB.UpdateInstance(instance1).IsNone()); From fab995d763958e8541d5b3a1322bdbb1e6654e3c Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 12 Dec 2025 18:00:41 +0200 Subject: [PATCH 009/171] pbconvert: add convert for sm message Signed-off-by: Mykola Solianko Reviewed-by: Mykola Kobets Reviewed-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko --- src/common/pbconvert/common.cpp | 15 ++ src/common/pbconvert/common.hpp | 8 ++ src/common/pbconvert/sm.cpp | 241 ++++++++++++++++++++++++++++++++ src/common/pbconvert/sm.hpp | 63 +++++++++ 4 files changed, 327 insertions(+) diff --git a/src/common/pbconvert/common.cpp b/src/common/pbconvert/common.cpp index efc1ea7cc..6e2388ad4 100644 --- a/src/common/pbconvert/common.cpp +++ b/src/common/pbconvert/common.cpp @@ -104,6 +104,21 @@ google::protobuf::Timestamp TimestampToPB(const aos::Time& time) return result; } +void ConvertToAos(const ::common::v2::InstanceFilter& src, InstanceFilter& dst) +{ + if (!src.item_id().empty()) { + dst.mItemID.SetValue(src.item_id().c_str()); + } + + if (!src.subject_id().empty()) { + dst.mSubjectID.SetValue(src.subject_id().c_str()); + } + + if (src.instance() >= 0) { + dst.mInstance.SetValue(static_cast(src.instance())); + } +} + void ConvertOSInfoToProto(const OSInfo& src, iamanager::v6::OSInfo& dst) { dst.set_os(src.mOS.CStr()); diff --git a/src/common/pbconvert/common.hpp b/src/common/pbconvert/common.hpp index 7a331ac3e..82809a06f 100644 --- a/src/common/pbconvert/common.hpp +++ b/src/common/pbconvert/common.hpp @@ -68,6 +68,14 @@ InstanceIdent ConvertToAos(const ::common::v2::InstanceIdent& val); */ Optional