blob: b2e60c9e6772370ec349dec08a3342347f5cd490 [file] [log] [blame] [edit]
// Copyright 2019 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 <lib/syslog/cpp/macros.h>
#include "src/performance/trace_manager/tests/trace_manager_test.h"
namespace tracing {
namespace test {
using SessionState = TraceManagerTest::SessionState;
// This only works when no other condition could cause the loop to exit.
// E.g., This doesn't work if the state is kStopping or kTerminating as the
// transition to kStopped,kTerminated will also cause the loop to exit.
template <typename T>
fit::result<fuchsia_tracing_controller::StartError> TryStart(TraceManagerTest* fixture,
const T& interface_ptr) {
fit::result<fuchsia_tracing_controller::StartError> start_result = fit::ok();
fuchsia_tracing_controller::StartOptions start_options{
TraceManagerTest::GetDefaultStartOptions()};
bool start_completed = false;
interface_ptr->StartTracing({{std::move(start_options)}})
.ThenExactlyOnce(
[fixture, &start_completed,
&start_result](fidl::Result<fuchsia_tracing_controller::Session::StartTracing>& result) {
start_completed = true;
if (result.is_error()) {
if (result.error_value().is_domain_error()) {
start_result = fit::error(result.error_value().domain_error());
} else {
start_result = fit::error(fuchsia_tracing_controller::StartError::kNotInitialized);
}
} else {
start_result = fit::ok();
}
fixture->QuitLoop();
});
fixture->RunLoopUntilIdle();
FX_LOGS(DEBUG) << "Start loop done";
EXPECT_TRUE(start_completed);
return start_result;
}
template <typename T>
void TryExtraStart(TraceManagerTest* fixture, const T& interface_ptr) {
auto start_result{TryStart(fixture, interface_ptr)};
EXPECT_EQ(fixture->GetSessionState(), SessionState::kStarted);
EXPECT_TRUE(start_result.is_error());
EXPECT_EQ(start_result.error_value(), fuchsia_tracing_controller::StartError::kAlreadyStarted);
}
TEST_F(TraceManagerTest, ExtraStart) {
ConnectToProvisionerService();
EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name));
ASSERT_TRUE(InitializeSession());
ASSERT_TRUE(StartSession());
// Now try starting again.
TryExtraStart(this, session_client());
}
TEST_F(TraceManagerTest, StartWhileStopping) {
ConnectToProvisionerService();
EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name));
ASSERT_TRUE(InitializeSession());
ASSERT_TRUE(StartSession());
fuchsia_tracing_controller::StopOptions stop_options{GetDefaultStopOptions()};
session_client()->StopTracing({{std::move(stop_options)}}).ThenExactlyOnce([](auto& result) {
ASSERT_TRUE(result.is_ok());
});
RunLoopUntilIdle();
// The loop will exit for the transition to kStopping.
FX_LOGS(DEBUG) << "Loop done, expecting session stopping";
ASSERT_EQ(GetSessionState(), SessionState::kStopping);
// Now try a Start while we're still in |kStopping|.
// The provider doesn't advance state until we tell it to, so we should
// still remain in |kStopping|.
fit::result<fuchsia_tracing_controller::StartError> start_result = fit::ok();
fuchsia_tracing_controller::StartOptions start_options{GetDefaultStartOptions()};
bool start_completed = false;
session_client()
->StartTracing({{std::move(start_options)}})
.ThenExactlyOnce(
[this, &start_completed,
&start_result](fidl::Result<fuchsia_tracing_controller::Session::StartTracing>& result) {
start_completed = true;
if (result.is_error()) {
if (result.error_value().is_domain_error()) {
start_result = fit::error(result.error_value().domain_error());
} else {
start_result = fit::error(fuchsia_tracing_controller::StartError::kNotInitialized);
}
} else {
start_result = fit::ok();
}
QuitLoop();
});
RunLoopUntilIdle();
FX_LOGS(DEBUG) << "Start loop done";
EXPECT_TRUE(GetSessionState() == SessionState::kStopping);
ASSERT_TRUE(start_completed);
ASSERT_TRUE(start_result.is_error());
EXPECT_EQ(start_result.error_value(), fuchsia_tracing_controller::StartError::kStopping);
MarkAllProvidersStopped();
RunLoopUntilIdle();
}
} // namespace test
} // namespace tracing