blob: f96b89dba49ee7a3e57228a5f6a24ae795094c36 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/modular/bin/basemgr/session_context_impl.h"
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/sys/cpp/testing/fake_launcher.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include "lib/sys/cpp/testing/test_with_environment.h"
#include "src/lib/files/path.h"
#include "src/modular/bin/basemgr/sessions.h"
#include "src/modular/lib/modular_config/modular_config.h"
#include "src/modular/lib/modular_config/modular_config_accessor.h"
#include "src/modular/lib/modular_config/modular_config_constants.h"
namespace modular_testing {
namespace {
class SessionContextImplTest : public sys::testing::TestWithEnvironment {
public:
// Returns a ModuleConfigAccessor that returns true for |use_random_session_id|.
static modular::ModularConfigAccessor ConfigWithRandomId() {
auto config_accessor = modular::ModularConfigAccessor(modular::DefaultConfig());
config_accessor.set_use_random_session_id(true);
return config_accessor;
}
// Deletes all session directories that are used to determine which sessions have been created.
// This does not erase any existing isolated storage.
static void DeleteAllSessionDirectories() {
std::vector<std::string> session_ids = modular::sessions::GetExistingSessionIds();
for (const auto& session_id : session_ids) {
auto session_dir = modular::sessions::GetSessionDirectory(session_id);
EXPECT_TRUE(files::DeletePath(session_dir, /*recursive=*/true));
}
}
modular::SessionContextImpl CreateSessionContextImpl(
modular::ModularConfigAccessor* modular_config,
modular::SessionContextImpl::OnSessionShutdownCallback on_session_shutdown) {
static constexpr auto kTestSessionmgrUrl = "test_sessionmgr_url";
sys::testing::FakeLauncher launcher;
// Register a fake sessionmgr component that never launches.
fuchsia::modular::session::AppConfig sessionmgr_app_config;
sessionmgr_app_config.set_url(kTestSessionmgrUrl);
launcher.RegisterComponent(
kTestSessionmgrUrl,
[](fuchsia::sys::LaunchInfo /* unused */,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> /* unused */) {});
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
return modular::SessionContextImpl{
&launcher, real_env().get(), std::move(sessionmgr_app_config), modular_config,
std::move(view_token),
/*additional_services_for_sessionmgr=*/nullptr,
/*additional_services_for_agents=*/fuchsia::sys::ServiceList(),
/*get_presentation=*/
[](fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> /* unused */) {},
std::move(on_session_shutdown)};
}
};
TEST_F(SessionContextImplTest, StartSessionmgr) {
sys::testing::FakeLauncher launcher;
std::string url = "test_url_string";
fuchsia::modular::session::AppConfig sessionmgr_app_config;
sessionmgr_app_config.set_url(url);
bool callback_called = false;
launcher.RegisterComponent(
url,
[&callback_called](fuchsia::sys::LaunchInfo /* unused */,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> /* unused */) {
callback_called = true;
});
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
auto modular_config_accessor = modular::ModularConfigAccessor(modular::DefaultConfig());
modular::SessionContextImpl impl(
&launcher, real_env().get(), std::move(sessionmgr_app_config), &modular_config_accessor,
std::move(view_token),
/*additional_services_for_sessionmgr=*/nullptr,
/*additional_services_for_agents=*/fuchsia::sys::ServiceList(),
/*get_presentation=*/
[](fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> /* unused */) {},
/*on_session_shutdown=*/[](modular::SessionContextImpl::ShutDownReason /* unused */) {});
EXPECT_TRUE(callback_called);
}
TEST_F(SessionContextImplTest, SessionmgrCrashInvokesDoneCallback) {
// Program the fake launcher to drop the CreateComponent request such that
// the error handler of the sessionmgr_app is invoked. This should invoke the
// done_callback.
sys::testing::FakeLauncher launcher;
std::string url = "test_url_string";
fuchsia::modular::session::AppConfig sessionmgr_app_config;
sessionmgr_app_config.set_url(url);
launcher.RegisterComponent(
url, [](fuchsia::sys::LaunchInfo /* unused */,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> /* unused */) {});
auto modular_config_accessor = modular::ModularConfigAccessor(modular::DefaultConfig());
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
bool done_callback_called = false;
modular::SessionContextImpl impl(
&launcher, real_env().get(), std::move(sessionmgr_app_config), &modular_config_accessor,
std::move(view_token),
/*additional_services_for_sessionmgr=*/nullptr,
/*additional_services_for_agents=*/fuchsia::sys::ServiceList(),
/*get_presentation=*/
[](fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> /* unused */) {},
/*on_session_shutdown=*/
[&done_callback_called](modular::SessionContextImpl::ShutDownReason /* unused */) {
done_callback_called = true;
});
RunLoopUntilIdle();
EXPECT_TRUE(done_callback_called);
}
TEST_F(SessionContextImplTest, DeleteEphemeralSessions) {
auto random_id_config = SessionContextImplTest::ConfigWithRandomId();
auto default_config = modular::ModularConfigAccessor(modular::DefaultConfig());
std::vector<std::string> existing_sessions;
// Start with zero sessions.
DeleteAllSessionDirectories();
// Create a session with a random ID.
auto is_random_id_session_shutdown{false};
auto random_id_session = CreateSessionContextImpl(
&random_id_config, [&](auto /*unused*/) { is_random_id_session_shutdown = true; });
RunLoopUntil([&]() { return is_random_id_session_shutdown; });
existing_sessions = modular::sessions::GetExistingSessionIds();
ASSERT_EQ(1u, existing_sessions.size());
EXPECT_NE(modular::sessions::GetStableSessionId(), existing_sessions.at(0));
// Create a session with the default config that uses the stable session ID.
auto is_stable_id_session_shutdown{false};
auto stable_id_session = CreateSessionContextImpl(
&default_config, [&](auto /*unused*/) { is_stable_id_session_shutdown = true; });
RunLoopUntil([&]() { return is_stable_id_session_shutdown; });
// The session with the random ID should have been deleted and replaced with the stable session.
existing_sessions = modular::sessions::GetExistingSessionIds();
ASSERT_EQ(1u, existing_sessions.size());
EXPECT_EQ(modular::sessions::GetStableSessionId(), existing_sessions.at(0));
}
} // namespace
} // namespace modular_testing