blob: 5aca8d605ad31ff7198199b4ad544e159741afe5 [file] [log] [blame]
// 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;
TEST_F(TraceManagerTest, RetryAfterFailedStop) {
ConnectToProvisionerService();
EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name));
ASSERT_TRUE(InitializeSession());
ASSERT_TRUE(StartSession());
controller::StopOptions stop_options{GetDefaultStopOptions()};
controller()->StopTracing(std::move(stop_options),
[](controller::Session_StopTracing_Result result) {
ASSERT_TRUE(result.is_err());
ASSERT_EQ(result.err(), controller::StopError::ABORTED);
});
RunLoopUntilIdle();
ASSERT_EQ(GetSessionState(), SessionState::kStopping);
// Drop the socket before marking all providers stopped. This causes
// an error while writing the buffer to the socket. Trace session should
// abort and terminate.
DropSocket();
MarkAllProvidersStopped();
RunLoopUntilIdle();
ASSERT_EQ(GetSessionState(), SessionState::kTerminating);
MarkAllProvidersTerminated();
RunLoopUntilIdle();
ASSERT_EQ(GetSessionState(), SessionState::kNonexistent);
// Initialize a new session and verify that everything works fine
zx::socket our_socket, their_socket;
zx_status_t status = zx::socket::create(0u, &our_socket, &their_socket);
ASSERT_EQ(status, ZX_OK);
controller::TraceConfig config{GetDefaultTraceConfig()};
provisioner()->InitializeTracing(NewControllerRequest(), std::move(config),
std::move(their_socket));
RunLoopUntilIdle();
ASSERT_EQ(GetSessionState(), SessionState::kInitialized);
RunLoopUntilIdle();
controller::StartOptions start_options{GetDefaultStartOptions()};
bool start_completed = false;
controller()->StartTracing(
std::move(start_options),
[this, &start_completed](controller::Session_StartTracing_Result in_result) {
start_completed = true;
QuitLoop();
});
RunLoopUntilIdle();
MarkAllProvidersStarted();
RunLoopUntilIdle();
ASSERT_EQ(GetSessionState(), SessionState::kStarted);
ASSERT_TRUE(StopSession());
ASSERT_TRUE(TerminateSession());
}
template <typename T>
void TryExtraStop(TraceManagerTest* fixture, const T& interface_ptr) {
controller::StopOptions stop_options{fixture->GetDefaultStopOptions()};
bool stop_completed = false;
interface_ptr->StopTracing(
std::move(stop_options),
[fixture, &stop_completed](controller::Session_StopTracing_Result result) {
ASSERT_TRUE(result.is_err());
ASSERT_EQ(result.err(), controller::StopError::NOT_STARTED);
stop_completed = true;
fixture->QuitLoop();
});
fixture->RunLoopUntilIdle();
FX_LOGS(DEBUG) << "Loop done, expecting session still stopped";
EXPECT_TRUE(stop_completed);
EXPECT_EQ(fixture->GetSessionState(), SessionState::kStopped);
}
TEST_F(TraceManagerTest, ExtraStop) {
ConnectToProvisionerService();
EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name));
ASSERT_TRUE(InitializeSession());
ASSERT_TRUE(StartSession());
ASSERT_TRUE(StopSession());
// Now try stopping again.
// This should complete with a NOT_STARTED error
TryExtraStop(this, controller());
}
TEST_F(TraceManagerTest, StopWhileStopping) {
ConnectToProvisionerService();
FakeProvider* provider;
EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name, &provider));
ASSERT_TRUE(InitializeSession());
ASSERT_TRUE(StartSession());
controller::StopOptions stop1_options{GetDefaultStopOptions()};
controller()->StopTracing(
std::move(stop1_options),
[](controller::Session_StopTracing_Result result) { ASSERT_TRUE(result.is_response()); });
RunLoopUntilIdle();
// The loop will exit for the transition to kStopping.
FX_LOGS(DEBUG) << "Loop done, expecting session stopping";
EXPECT_EQ(GetSessionState(), SessionState::kStopping);
// Now try another Stop while we're still in |kStopping|.
// The provider doesn't advance state until we tell it to, so we should
// still remain in |kStopping|.
controller::StopOptions stop2_options{GetDefaultStopOptions()};
bool stop_completed = false;
controller()->StopTracing(std::move(stop2_options),
[this, &stop_completed](controller::Session_StopTracing_Result result) {
ASSERT_TRUE(result.is_err());
ASSERT_EQ(result.err(), controller::StopError::NOT_STARTED);
stop_completed = true;
QuitLoop();
});
RunLoopUntilIdle();
FX_LOGS(DEBUG) << "Stop loop done";
EXPECT_TRUE(stop_completed);
EXPECT_TRUE(GetSessionState() == SessionState::kStopping);
}
} // namespace test
} // namespace tracing