| // 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 <src/lib/fxl/logging.h> |
| |
| #include "garnet/bin/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> |
| controller::Controller_StartTracing_Result TryStart(TraceManagerTest* fixture, |
| const T& interface_ptr) { |
| controller::Controller_StartTracing_Result start_result; |
| controller::StartOptions start_options{fixture->GetDefaultStartOptions()}; |
| bool start_completed = false; |
| interface_ptr->StartTracing(std::move(start_options), |
| [fixture, &start_completed, |
| &start_result](controller::Controller_StartTracing_Result result) { |
| start_completed = true; |
| start_result = std::move(result); |
| fixture->QuitLoop(); |
| }); |
| fixture->RunLoopUntilIdle(); |
| FX_VLOGS(2) << "Start loop done"; |
| EXPECT_TRUE(start_completed); |
| return start_result; |
| } |
| |
| TEST_F(TraceManagerTest, StartUninitialized) { |
| ConnectToControllerService(); |
| |
| controller::Controller_StartTracing_Result start_result{TryStart(this, controller())}; |
| EXPECT_TRUE(start_result.is_err()); |
| EXPECT_EQ(start_result.err(), controller::StartErrorCode::NOT_INITIALIZED); |
| } |
| |
| template <typename T> |
| void TryExtraStart(TraceManagerTest* fixture, const T& interface_ptr) { |
| controller::Controller_StartTracing_Result start_result{TryStart(fixture, interface_ptr)}; |
| EXPECT_EQ(fixture->GetSessionState(), SessionState::kStarted); |
| EXPECT_TRUE(start_result.is_err()); |
| EXPECT_EQ(start_result.err(), controller::StartErrorCode::ALREADY_STARTED); |
| } |
| |
| TEST_F(TraceManagerTest, ExtraStart) { |
| ConnectToControllerService(); |
| |
| EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name)); |
| |
| ASSERT_TRUE(InitializeSession()); |
| |
| ASSERT_TRUE(StartSession()); |
| |
| // Now try starting again. |
| TryExtraStart(this, controller()); |
| } |
| |
| TEST_F(TraceManagerTest, StartWhileStopping) { |
| ConnectToControllerService(); |
| |
| EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name)); |
| |
| ASSERT_TRUE(InitializeSession()); |
| |
| ASSERT_TRUE(StartSession()); |
| |
| controller::StopOptions stop_options{GetDefaultStopOptions()}; |
| controller()->StopTracing(std::move(stop_options), []() {}); |
| RunLoopUntilIdle(); |
| // The loop will exit for the transition to kStopping. |
| FX_VLOGS(2) << "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|. |
| controller::Controller_StartTracing_Result result; |
| controller::StartOptions start_options{GetDefaultStartOptions()}; |
| bool start_completed = false; |
| controller()->StartTracing( |
| std::move(start_options), |
| [this, &start_completed, &result](controller::Controller_StartTracing_Result in_result) { |
| start_completed = true; |
| result = std::move(in_result); |
| QuitLoop(); |
| }); |
| RunLoopUntilIdle(); |
| FX_VLOGS(2) << "Start loop done"; |
| EXPECT_TRUE(GetSessionState() == SessionState::kStopping); |
| ASSERT_TRUE(start_completed); |
| ASSERT_TRUE(result.is_err()); |
| EXPECT_EQ(result.err(), controller::StartErrorCode::STOPPING); |
| } |
| |
| TEST_F(TraceManagerTest, StartWhileTerminating) { |
| ConnectToControllerService(); |
| |
| EXPECT_TRUE(AddFakeProvider(kProvider1Pid, kProvider1Name)); |
| |
| ASSERT_TRUE(InitializeSession()); |
| |
| ASSERT_TRUE(StartSession()); |
| |
| ASSERT_TRUE(StopSession()); |
| |
| controller::TerminateOptions options{GetDefaultTerminateOptions()}; |
| controller()->TerminateTracing(std::move(options), [](controller::TerminateResult result) {}); |
| RunLoopUntilIdle(); |
| ASSERT_EQ(GetSessionState(), SessionState::kTerminating); |
| |
| // Now try a Start while we're still in |kTerminating|. |
| // The provider doesn't advance state until we tell it to, so we should |
| // still remain in |kTerminating|. |
| controller::Controller_StartTracing_Result result; |
| controller::StartOptions start_options{GetDefaultStartOptions()}; |
| bool start_completed = false; |
| controller()->StartTracing( |
| std::move(start_options), |
| [this, &start_completed, &result](controller::Controller_StartTracing_Result in_result) { |
| start_completed = true; |
| result = std::move(in_result); |
| QuitLoop(); |
| }); |
| RunLoopUntilIdle(); |
| FX_VLOGS(2) << "Start loop done"; |
| EXPECT_TRUE(GetSessionState() == SessionState::kTerminating); |
| ASSERT_TRUE(start_completed); |
| ASSERT_TRUE(result.is_err()); |
| EXPECT_EQ(result.err(), controller::StartErrorCode::TERMINATING); |
| } |
| |
| } // namespace test |
| } // namespace tracing |