Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/core/sm/launcher/itf/runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ class RuntimeItf : public monitoring::InstanceMonitoringProviderItf {
*/
virtual Error GetRuntimeInfo(RuntimeInfo& runtimeInfo) const = 0;

/**
* Initializes instances.
*
* Launcher provides list of known instances to runtime at startup. Runtime should stop all instances that are not
* in the list and properly initialize already running instances. Runtime should not start any instance at this
* stage, it should only prepare them for future start.
*
* @param instancesInfo instances info.
* @return Error.
*/
virtual Error InitInstances(const Array<InstanceInfo>& instancesInfo) = 0;

/**
* Start instance.
*
Expand Down
29 changes: 29 additions & 0 deletions src/core/sm/launcher/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ Error Launcher::Start()
return AOS_ERROR_WRAP(err);
}

InitInstances(*storedInstances);

lock.Unlock();

LoadInstancesData(*storedInstances);
Expand Down Expand Up @@ -361,6 +363,33 @@ void Launcher::OnDisconnect()
StartTTLTimer();
}

void Launcher::InitInstances(const Array<InstanceInfo>& instancesInfo)
{
LOG_DBG() << "Init instances" << Log::Field("numInstances", instancesInfo.Size());

for (auto& it : mRuntimes) {
auto runtimeInstances = MakeUnique<InstanceInfoArray>(&mAllocator);

for (const auto& instanceInfo : instancesInfo) {
if (instanceInfo.mRuntimeID != it.mSecond) {
continue;
}

if (auto err = runtimeInstances->PushBack(instanceInfo); !err.IsNone()) {
LOG_ERR() << "Failed to add instance to runtime init list" << Log::Field("instance", instanceInfo)
<< Log::Field(AOS_ERROR_WRAP(err));

break;
}
}

if (auto err = it.mFirst->InitInstances(*runtimeInstances); !err.IsNone()) {
LOG_ERR() << "Failed to init instances" << Log::Field("runtimeID", it.mSecond)
<< Log::Field(AOS_ERROR_WRAP(err));
}
}
}

void Launcher::RunRebootThread()
{
while (true) {
Expand Down
5 changes: 3 additions & 2 deletions src/core/sm/launcher/launcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,15 @@ class Launcher : public LauncherItf,
static constexpr auto cMaxNumSubscribers = 4;

static constexpr auto cAllocatorSize = 2 * sizeof(StaticArray<InstanceIdent, cMaxNumInstances>)
+ 2 * sizeof(InstanceInfoArray) + sizeof(InstanceStatusArray)
+ 3 * sizeof(InstanceInfoArray) + sizeof(InstanceStatusArray)
+ cMaxNumConcurrentItems
* (sizeof(oci::ImageConfig) + sizeof(oci::ItemConfig)
+ Max(sizeof(StaticString<cFilePathLen>) + sizeof(oci::ImageManifest),
sizeof(networkmanager::InstanceNetworkConfig) + sizeof(resourcemanager::ResourceInfo)))
+ Max(sizeof(StaticArray<UpdateItemInfo, cMaxNumUpdateItems>),
sizeof(StaticArray<imagemanager::UpdateItemInfo, cMaxNumUpdateItems>)
+ sizeof(StaticArray<imagemanager::UpdateItemStatus, cMaxNumUpdateItems>));
static constexpr auto cMaxNumAllocations = 4 + cMaxNumConcurrentItems * 4;
static constexpr auto cMaxNumAllocations = 5 + cMaxNumConcurrentItems * 4;

void OnConnect() override;
void OnDisconnect() override;
Expand Down Expand Up @@ -233,6 +233,7 @@ class Launcher : public LauncherItf,
void StartTTLTimer();
void StopExpiredInstances(UniqueLock<Mutex>& lock);
void SendNodeInstancesStatuses();
void InitInstances(const Array<InstanceInfo>& instancesInfo);

StaticAllocator<cAllocatorSize, cMaxNumAllocations> mAllocator;
StaticArray<instancestatusprovider::ListenerItf*, cMaxNumSubscribers> mSubscribers;
Expand Down
59 changes: 59 additions & 0 deletions src/core/sm/launcher/tests/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,13 @@ class LauncherTest : public Test {
EXPECT_CALL(mRuntime0, Stop).WillRepeatedly(Return(ErrorEnum::eNone));
EXPECT_CALL(mRuntime0, GetRuntimeInfo)
.WillRepeatedly(DoAll(SetArgReferee<0>(CreateRuntimeInfo("runtime0")), Return(ErrorEnum::eNone)));
EXPECT_CALL(mRuntime0, InitInstances).WillRepeatedly(Return(ErrorEnum::eNone));

EXPECT_CALL(mRuntime1, Start).WillRepeatedly(Return(ErrorEnum::eNone));
EXPECT_CALL(mRuntime1, Stop).WillRepeatedly(Return(ErrorEnum::eNone));
EXPECT_CALL(mRuntime1, GetRuntimeInfo)
.WillRepeatedly(DoAll(SetArgReferee<0>(CreateRuntimeInfo("runtime1")), Return(ErrorEnum::eNone)));
EXPECT_CALL(mRuntime1, InitInstances).WillRepeatedly(Return(ErrorEnum::eNone));

mImageManifest.mItemConfig.EmplaceValue();

Expand Down Expand Up @@ -246,6 +248,63 @@ TEST_F(LauncherTest, NoStoredInstancesOnModuleStart)
ASSERT_TRUE(err.IsNone()) << tests::utils::ErrorToStr(err);
}

TEST_F(LauncherTest, InitInstances)
{
const std::vector cStoredInfos = {
CreateInstanceInfo("item0", 0, "1.0.0", "runtime0"),
CreateInstanceInfo("item1", 1, "1.0.0", "runtime1"),
CreateInstanceInfo("item2", 2, "1.0.0", "runtime0"),
};

const std::vector cRuntime0Infos = {cStoredInfos[0], cStoredInfos[2]};
const std::vector cRuntime1Infos = {cStoredInfos[1]};

mStorage.Init(cStoredInfos);

auto err = mLauncher.Init(GetRuntimesArray(), mImageManager, mSender, mStorage, mOCISpec, mItemInfoProvider,
mCloudConnection, mNetworkManager, mInstanceIDProvider, mResourceInfoProvider);
ASSERT_TRUE(err.IsNone()) << tests::utils::ErrorToStr(err);

EXPECT_CALL(mRuntime0, InitInstances(Array<InstanceInfo>(&cRuntime0Infos.front(), cRuntime0Infos.size())))
.WillOnce(Return(ErrorEnum::eNone));
EXPECT_CALL(mRuntime1, InitInstances(Array<InstanceInfo>(&cRuntime1Infos.front(), cRuntime1Infos.size())))
.WillOnce(Return(ErrorEnum::eNone));

EXPECT_CALL(mRuntime0, StartInstance)
.WillRepeatedly(Invoke([](const InstanceInfo& instance, InstanceStatus& status) {
SetInstanceStatus(instance, InstanceStateEnum::eActive, status);

return ErrorEnum::eNone;
}));

EXPECT_CALL(mRuntime1, StartInstance)
.WillRepeatedly(Invoke([](const InstanceInfo& instance, InstanceStatus& status) {
SetInstanceStatus(instance, InstanceStateEnum::eActive, status);

return ErrorEnum::eNone;
}));

err = mLauncher.Start();
ASSERT_TRUE(err.IsNone()) << tests::utils::ErrorToStr(err);

EXPECT_CALL(mRuntime0, StopInstance)
.WillRepeatedly(Invoke([](const InstanceIdent& instance, InstanceStatus& status) {
SetInstanceStatus(instance, InstanceStateEnum::eInactive, status);

return ErrorEnum::eNone;
}));

EXPECT_CALL(mRuntime1, StopInstance)
.WillRepeatedly(Invoke([](const InstanceIdent& instance, InstanceStatus& status) {
SetInstanceStatus(instance, InstanceStateEnum::eInactive, status);

return ErrorEnum::eNone;
}));

err = mLauncher.Stop();
ASSERT_TRUE(err.IsNone()) << tests::utils::ErrorToStr(err);
}

TEST_F(LauncherTest, SendActiveComponentNodeInstancesStatusOnModuleStart)
{
const std::vector cRuntime0Components = {
Expand Down
1 change: 1 addition & 0 deletions src/core/sm/launcher/tests/mocks/runtimemock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class RuntimeMock : public RuntimeItf {
MOCK_METHOD(Error, Start, (), (override));
MOCK_METHOD(Error, Stop, (), (override));
MOCK_METHOD(Error, GetRuntimeInfo, (RuntimeInfo&), (const, override));
MOCK_METHOD(Error, InitInstances, (const Array<InstanceInfo>&), (override));
MOCK_METHOD(Error, StartInstance, (const InstanceInfo&, InstanceStatus&), (override));
MOCK_METHOD(Error, StopInstance, (const InstanceIdent&, InstanceStatus&), (override));
MOCK_METHOD(Error, Reboot, (), (override));
Expand Down
Loading