/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/tracing/core/shared_memory_arbiter_impl.h"

#include <bitset>
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/commit_data_request.h"
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "src/base/test/gtest_test_suite.h"
#include "src/base/test/test_task_runner.h"
#include "src/tracing/core/patch_list.h"
#include "src/tracing/test/aligned_buffer_test.h"
#include "src/tracing/test/mock_producer_endpoint.h"
#include "test/gtest_and_gmock.h"

#include "protos/perfetto/trace/test_event.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {

using testing::_;
using testing::Between;
using testing::Invoke;
using testing::Mock;
using testing::NiceMock;
using testing::UnorderedElementsAreArray;

class SharedMemoryArbiterImplTest : public AlignedBufferTest {
 public:
  void SetUp() override {
    default_layout_ =
        SharedMemoryArbiterImpl::default_page_layout_for_testing();
    AlignedBufferTest::SetUp();
    task_runner_.reset(new base::TestTaskRunner());
    arbiter_.reset(new SharedMemoryArbiterImpl(buf(), buf_size(), page_size(),
                                               &mock_producer_endpoint_,
                                               task_runner_.get()));
  }

  bool IsArbiterFullyBound() { return arbiter_->fully_bound_; }

  void TearDown() override {
    arbiter_.reset();
    task_runner_.reset();
    SharedMemoryArbiterImpl::set_default_layout_for_testing(default_layout_);
  }

  std::unique_ptr<base::TestTaskRunner> task_runner_;
  std::unique_ptr<SharedMemoryArbiterImpl> arbiter_;
  NiceMock<MockProducerEndpoint> mock_producer_endpoint_;
  std::function<void(const std::vector<uint32_t>&)> on_pages_complete_;
  SharedMemoryABI::PageLayout default_layout_;
};

size_t const kPageSizes[] = {4096, 65536};
INSTANTIATE_TEST_SUITE_P(PageSize,
                         SharedMemoryArbiterImplTest,
                         ::testing::ValuesIn(kPageSizes));

// The buffer has 14 pages (kNumPages), each will be partitioned in 14 chunks.
// The test requests 30 chunks (2 full pages + 2 chunks from a 3rd page) and
// releases them in different batches. It tests the consistency of the batches
// and the releasing order.
TEST_P(SharedMemoryArbiterImplTest, GetAndReturnChunks) {
  SharedMemoryArbiterImpl::set_default_layout_for_testing(
      SharedMemoryABI::PageLayout::kPageDiv14);
  static constexpr size_t kTotChunks = kNumPages * 14;
  SharedMemoryABI::Chunk chunks[kTotChunks];
  for (size_t i = 0; i < 14 * 2 + 2; i++) {
    chunks[i] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kStall);
    ASSERT_TRUE(chunks[i].is_valid());
  }

  // Finally return the first 28 chunks (full 2 pages) and only the 2nd chunk of
  // the 2rd page. Chunks are release in interleaved order: 1,0,3,2,5,4,7,6.
  // Check that the notification callback is posted and order is consistent.
  auto on_commit_1 = task_runner_->CreateCheckpoint("on_commit_1");
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
      .WillOnce(Invoke([on_commit_1](const CommitDataRequest& req,
                                     MockProducerEndpoint::CommitDataCallback) {
        ASSERT_EQ(14 * 2 + 1, req.chunks_to_move_size());
        for (size_t i = 0; i < 14 * 2; i++) {
          ASSERT_EQ(i / 14, req.chunks_to_move()[i].page());
          ASSERT_EQ((i % 14) ^ 1, req.chunks_to_move()[i].chunk());
          ASSERT_EQ(i % 5 + 1, req.chunks_to_move()[i].target_buffer());
        }
        ASSERT_EQ(2u, req.chunks_to_move()[28].page());
        ASSERT_EQ(1u, req.chunks_to_move()[28].chunk());
        ASSERT_EQ(42u, req.chunks_to_move()[28].target_buffer());
        on_commit_1();
      }));
  PatchList ignored;
  for (size_t i = 0; i < 14 * 2; i++) {
    arbiter_->ReturnCompletedChunk(std::move(chunks[i ^ 1]), i % 5 + 1,
                                   &ignored);
  }
  arbiter_->ReturnCompletedChunk(std::move(chunks[29]), 42, &ignored);
  task_runner_->RunUntilCheckpoint("on_commit_1");

  // Then release the 1st chunk of the 3rd page, and check that we get a
  // notification for that as well.
  auto on_commit_2 = task_runner_->CreateCheckpoint("on_commit_2");
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
      .WillOnce(Invoke([on_commit_2](const CommitDataRequest& req,
                                     MockProducerEndpoint::CommitDataCallback) {
        ASSERT_EQ(1, req.chunks_to_move_size());
        ASSERT_EQ(2u, req.chunks_to_move()[0].page());
        ASSERT_EQ(0u, req.chunks_to_move()[0].chunk());
        ASSERT_EQ(43u, req.chunks_to_move()[0].target_buffer());
        on_commit_2();
      }));
  arbiter_->ReturnCompletedChunk(std::move(chunks[28]), 43, &ignored);
  task_runner_->RunUntilCheckpoint("on_commit_2");
}

TEST_P(SharedMemoryArbiterImplTest, BatchCommits) {
  SharedMemoryArbiterImpl::set_default_layout_for_testing(
      SharedMemoryABI::PageLayout::kPageDiv1);

  // Batching period is 0s - chunks are being committed as soon as they are
  // returned.
  SharedMemoryABI::Chunk chunk =
      arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDefault);
  ASSERT_TRUE(chunk.is_valid());
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _)).Times(1);
  PatchList ignored;
  arbiter_->ReturnCompletedChunk(std::move(chunk), 0, &ignored);
  task_runner_->RunUntilIdle();
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock_producer_endpoint_));

  // Since we cannot explicitly control the passage of time in task_runner_, to
  // simulate a non-zero batching period and a commit at the end of it, set the
  // batching duration to a very large value and call
  // FlushPendingCommitDataRequests to manually trigger the commit.
  arbiter_->SetDirectSMBPatchingSupportedByService();
  ASSERT_TRUE(arbiter_->EnableDirectSMBPatching());
  arbiter_->SetBatchCommitsDuration(UINT32_MAX);

  // First chunk that will be batched. CommitData should not be called
  // immediately this time.
  chunk = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDefault);
  ASSERT_TRUE(chunk.is_valid());
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _)).Times(0);
  // We'll pretend that the chunk needs patching. This is done in order to
  // verify that chunks that need patching are not marked as complete (i.e. they
  // are kept in state kChunkBeingWritten) before the batching period ends - in
  // case a patch for them arrives during the batching period.
  chunk.SetFlag(SharedMemoryABI::ChunkHeader::kChunkNeedsPatching);
  arbiter_->ReturnCompletedChunk(std::move(chunk), 1, &ignored);
  task_runner_->RunUntilIdle();
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock_producer_endpoint_));
  ASSERT_EQ(SharedMemoryABI::kChunkBeingWritten,
            arbiter_->shmem_abi_for_testing()->GetChunkState(1u, 0u));

  // Add a second chunk to the batch. This should also not trigger an immediate
  // call to CommitData.
  chunk = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDefault);
  ASSERT_TRUE(chunk.is_valid());
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _)).Times(0);
  arbiter_->ReturnCompletedChunk(std::move(chunk), 2, &ignored);
  task_runner_->RunUntilIdle();
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock_producer_endpoint_));
  // This chunk does not need patching, so it should be marked as complete even
  // before the end of the batching period - to allow the service to read it in
  // full.
  ASSERT_EQ(SharedMemoryABI::kChunkComplete,
            arbiter_->shmem_abi_for_testing()->GetChunkState(2u, 0u));

  // Make sure that CommitData gets called once (should happen at the end
  // of the batching period), with the two chunks in the batch.
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
      .WillOnce(Invoke([](const CommitDataRequest& req,
                          MockProducerEndpoint::CommitDataCallback) {
        ASSERT_EQ(2, req.chunks_to_move_size());

        // Verify that this is the first chunk that we expect to have been
        // batched.
        ASSERT_EQ(1u, req.chunks_to_move()[0].page());
        ASSERT_EQ(0u, req.chunks_to_move()[0].chunk());
        ASSERT_EQ(1u, req.chunks_to_move()[0].target_buffer());

        // Verify that this is the second chunk that we expect to have been
        // batched.
        ASSERT_EQ(2u, req.chunks_to_move()[1].page());
        ASSERT_EQ(0u, req.chunks_to_move()[1].chunk());
        ASSERT_EQ(2u, req.chunks_to_move()[1].target_buffer());
      }));

  // Pretend we've reached the end of the batching period.
  arbiter_->FlushPendingCommitDataRequests();
}

// Check that we can actually create up to kMaxWriterID TraceWriter(s).
TEST_P(SharedMemoryArbiterImplTest, WriterIDsAllocation) {
  auto checkpoint = task_runner_->CreateCheckpoint("last_unregistered");

  std::vector<uint32_t> registered_ids;
  std::vector<uint32_t> unregistered_ids;

  ON_CALL(mock_producer_endpoint_, RegisterTraceWriter)
      .WillByDefault(
          [&](uint32_t id, uint32_t) { registered_ids.push_back(id); });
  ON_CALL(mock_producer_endpoint_, UnregisterTraceWriter)
      .WillByDefault([&](uint32_t id) {
        unregistered_ids.push_back(id);
        if (unregistered_ids.size() == kMaxWriterID) {
          checkpoint();
        }
      });
  {
    std::map<WriterID, std::unique_ptr<TraceWriter>> writers;

    for (size_t i = 0; i < kMaxWriterID; i++) {
      std::unique_ptr<TraceWriter> writer = arbiter_->CreateTraceWriter(1);
      ASSERT_TRUE(writer);
      WriterID writer_id = writer->writer_id();
      ASSERT_TRUE(writers.emplace(writer_id, std::move(writer)).second);
    }

    // A further call should return a null impl of trace writer as we exhausted
    // writer IDs.
    ASSERT_EQ(arbiter_->CreateTraceWriter(1)->writer_id(), 0);
  }

  // This should run the Register/UnregisterTraceWriter tasks enqueued by the
  // memory arbiter.
  task_runner_->RunUntilCheckpoint("last_unregistered", 15000);

  std::vector<uint32_t> expected_ids;  // 1..kMaxWriterID
  for (uint32_t i = 1; i <= kMaxWriterID; i++)
    expected_ids.push_back(i);
  EXPECT_THAT(registered_ids, UnorderedElementsAreArray(expected_ids));
  EXPECT_THAT(unregistered_ids, UnorderedElementsAreArray(expected_ids));
}

TEST_P(SharedMemoryArbiterImplTest, Shutdown) {
  std::unique_ptr<TraceWriter> writer = arbiter_->CreateTraceWriter(1);
  EXPECT_TRUE(writer);
  EXPECT_FALSE(arbiter_->TryShutdown());

  // We still get a valid trace writer after shutdown, but it's a null one
  // that's not connected to the arbiter.
  std::unique_ptr<TraceWriter> writer2 = arbiter_->CreateTraceWriter(2);
  EXPECT_TRUE(writer2);
  EXPECT_EQ(writer2->writer_id(), 0);

  // Shutdown will succeed once the only non-null writer goes away.
  writer.reset();
  EXPECT_TRUE(arbiter_->TryShutdown());
}

// Verify that getting a new chunk doesn't stall when kDrop policy is chosen.
TEST_P(SharedMemoryArbiterImplTest, BufferExhaustedPolicyDrop) {
  // Grab all chunks in the SMB.
  SharedMemoryArbiterImpl::set_default_layout_for_testing(
      SharedMemoryABI::PageLayout::kPageDiv1);
  static constexpr size_t kTotChunks = kNumPages;
  SharedMemoryABI::Chunk chunks[kTotChunks];
  for (size_t i = 0; i < kTotChunks; i++) {
    chunks[i] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
    ASSERT_TRUE(chunks[i].is_valid());
  }

  // SMB is exhausted, thus GetNewChunk() should return an invalid chunk. In
  // kStall mode, this would stall.
  SharedMemoryABI::Chunk invalid_chunk =
      arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
  ASSERT_FALSE(invalid_chunk.is_valid());

  // Returning the chunk is not enough to be able to reacquire it.
  PatchList ignored;
  arbiter_->ReturnCompletedChunk(std::move(chunks[0]), 1, &ignored);

  invalid_chunk = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
  ASSERT_FALSE(invalid_chunk.is_valid());

  // After releasing the chunk as free, we can reacquire it.
  chunks[0] =
      arbiter_->shmem_abi_for_testing()->TryAcquireChunkForReading(0, 0);
  ASSERT_TRUE(chunks[0].is_valid());
  arbiter_->shmem_abi_for_testing()->ReleaseChunkAsFree(std::move(chunks[0]));

  chunks[0] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
  ASSERT_TRUE(chunks[0].is_valid());
}

TEST_P(SharedMemoryArbiterImplTest, CreateUnboundAndBind) {
  auto checkpoint_writer = task_runner_->CreateCheckpoint("writer_registered");
  auto checkpoint_flush = task_runner_->CreateCheckpoint("flush_completed");

  // Create an unbound arbiter and bind immediately.
  arbiter_.reset(new SharedMemoryArbiterImpl(buf(), buf_size(), page_size(),
                                             nullptr, nullptr));
  arbiter_->BindToProducerEndpoint(&mock_producer_endpoint_,
                                   task_runner_.get());
  EXPECT_TRUE(IsArbiterFullyBound());

  // Trace writer should be registered in a non-delayed task.
  EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, 1))
      .WillOnce(testing::InvokeWithoutArgs(checkpoint_writer));
  std::unique_ptr<TraceWriter> writer =
      arbiter_->CreateTraceWriter(1, BufferExhaustedPolicy::kDrop);
  task_runner_->RunUntilCheckpoint("writer_registered", 5000);

  // Commits/flushes should be sent right away.
  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
      .WillOnce(testing::InvokeArgument<1>());
  writer->Flush(checkpoint_flush);
  task_runner_->RunUntilCheckpoint("flush_completed", 5000);
}

// Startup tracing tests are run with the arbiter in either bound or unbound
// initial state. Startup tracing in bound state can still be useful, e.g. in
// integration tests or to enable tracing in the consumer process immediately
// before/after instructing the service to start a session, avoiding the
// round-trip time through the service.
enum class InitialBindingState { kUnbound, kBound };

class SharedMemoryArbiterImplStartupTracingTest
    : public SharedMemoryArbiterImplTest {
 public:
  void SetupArbiter(InitialBindingState initial_state) {
    if (initial_state == InitialBindingState::kUnbound) {
      arbiter_.reset(new SharedMemoryArbiterImpl(buf(), buf_size(), page_size(),
                                                 nullptr, nullptr));
      EXPECT_FALSE(IsArbiterFullyBound());
    } else {
      // A bound arbiter is already set up by the base class.
      EXPECT_TRUE(IsArbiterFullyBound());
    }
  }

  void EnsureArbiterBoundToEndpoint(InitialBindingState initial_state) {
    if (initial_state == InitialBindingState::kUnbound) {
      arbiter_->BindToProducerEndpoint(&mock_producer_endpoint_,
                                       task_runner_.get());
    }
  }

  void TestStartupTracing(InitialBindingState initial_state) {
    constexpr uint16_t kTargetBufferReservationId1 = 1;
    constexpr uint16_t kTargetBufferReservationId2 = 2;

    SetupArbiter(initial_state);

    // Create an unbound startup writer.
    std::unique_ptr<TraceWriter> writer =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);
    EXPECT_FALSE(IsArbiterFullyBound());

    // Write two packets while unbound (if InitialBindingState::kUnbound) and
    // flush the chunk after each packet. The writer will return the chunk to
    // the arbiter and grab a new chunk for the second packet. The flush should
    // only add the chunk into the queued commit request.
    for (int i = 0; i < 2; i++) {
      {
        auto packet = writer->NewTracePacket();
        packet->set_for_testing()->set_str("foo");
      }
      writer->Flush();
    }

    // Bind to producer endpoint if initially unbound. This should not register
    // the trace writer yet, because its buffer reservation is still unbound.
    EnsureArbiterBoundToEndpoint(initial_state);
    EXPECT_FALSE(IsArbiterFullyBound());

    // Write another packet into another chunk and queue it.
    {
      auto packet = writer->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    bool flush_completed = false;
    writer->Flush([&flush_completed] { flush_completed = true; });

    // Bind the buffer reservation to a buffer. Trace writer should be
    // registered and queued commits flushed.
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, 42));
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke([](const CommitDataRequest& req,
                            MockProducerEndpoint::CommitDataCallback callback) {
          ASSERT_EQ(3, req.chunks_to_move_size());
          EXPECT_EQ(42u, req.chunks_to_move()[0].target_buffer());
          EXPECT_EQ(42u, req.chunks_to_move()[1].target_buffer());
          EXPECT_EQ(42u, req.chunks_to_move()[2].target_buffer());
          callback();
        }));

    arbiter_->BindStartupTargetBuffer(kTargetBufferReservationId1, 42);
    EXPECT_TRUE(IsArbiterFullyBound());

    testing::Mock::VerifyAndClearExpectations(&mock_producer_endpoint_);
    EXPECT_TRUE(flush_completed);

    // Creating a new startup writer for the same buffer posts an immediate task
    // to register it.
    auto checkpoint_register1b =
        task_runner_->CreateCheckpoint("writer1b_registered");
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, 42))
        .WillOnce(testing::InvokeWithoutArgs(checkpoint_register1b));
    std::unique_ptr<TraceWriter> writer1b =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);
    task_runner_->RunUntilCheckpoint("writer1b_registered", 5000);

    // And a commit on this new writer should be flushed to the right buffer,
    // too.
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke([](const CommitDataRequest& req,
                            MockProducerEndpoint::CommitDataCallback callback) {
          ASSERT_EQ(1, req.chunks_to_move_size());
          EXPECT_EQ(42u, req.chunks_to_move()[0].target_buffer());
          callback();
        }));
    {
      auto packet = writer1b->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    flush_completed = false;
    writer1b->Flush([&flush_completed] { flush_completed = true; });

    testing::Mock::VerifyAndClearExpectations(&mock_producer_endpoint_);
    EXPECT_TRUE(flush_completed);

    // Create another startup writer for another target buffer, which puts the
    // arbiter back into unbound state.
    std::unique_ptr<TraceWriter> writer2 =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId2);
    EXPECT_FALSE(IsArbiterFullyBound());

    // Write a chunk into both writers. Both should be queued up into the next
    // commit request.
    {
      auto packet = writer->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    writer->Flush();
    {
      auto packet = writer2->NewTracePacket();
      packet->set_for_testing()->set_str("bar");
    }
    flush_completed = false;
    writer2->Flush([&flush_completed] { flush_completed = true; });

    // Destroy the first trace writer, which should cause the arbiter to post a
    // task to unregister it.
    auto checkpoint_writer =
        task_runner_->CreateCheckpoint("writer_unregistered");
    EXPECT_CALL(mock_producer_endpoint_,
                UnregisterTraceWriter(writer->writer_id()))
        .WillOnce(testing::InvokeWithoutArgs(checkpoint_writer));
    writer.reset();
    task_runner_->RunUntilCheckpoint("writer_unregistered", 5000);

    // Bind the second buffer reservation to a buffer. Second trace writer
    // should be registered and queued commits flushed.
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, 23));
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke([](const CommitDataRequest& req,
                            MockProducerEndpoint::CommitDataCallback callback) {
          ASSERT_EQ(2, req.chunks_to_move_size());
          EXPECT_EQ(42u, req.chunks_to_move()[0].target_buffer());
          EXPECT_EQ(23u, req.chunks_to_move()[1].target_buffer());
          callback();
        }));

    arbiter_->BindStartupTargetBuffer(kTargetBufferReservationId2, 23);
    EXPECT_TRUE(IsArbiterFullyBound());

    testing::Mock::VerifyAndClearExpectations(&mock_producer_endpoint_);
    EXPECT_TRUE(flush_completed);
  }

  void TestAbortStartupTracingForReservation(
      InitialBindingState initial_state) {
    constexpr uint16_t kTargetBufferReservationId1 = 1;
    constexpr uint16_t kTargetBufferReservationId2 = 2;

    SetupArbiter(initial_state);

    // Create two unbound startup writers the same target buffer.
    SharedMemoryABI* shmem_abi = arbiter_->shmem_abi_for_testing();
    std::unique_ptr<TraceWriter> writer =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);
    std::unique_ptr<TraceWriter> writer2 =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);

    // Write two packet while unbound and flush the chunk after each packet. The
    // writer will return the chunk to the arbiter and grab a new chunk for the
    // second packet. The flush should only add the chunk into the queued commit
    // request.
    for (int i = 0; i < 2; i++) {
      {
        auto packet = writer->NewTracePacket();
        packet->set_for_testing()->set_str("foo");
      }
      writer->Flush();
    }

    // Expectations for the below calls.
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke([shmem_abi](const CommitDataRequest& req,
                                     MockProducerEndpoint::CommitDataCallback) {
          ASSERT_EQ(2, req.chunks_to_move_size());
          for (size_t i = 0; i < 2; i++) {
            EXPECT_EQ(0u, req.chunks_to_move()[i].target_buffer());
            SharedMemoryABI::Chunk chunk = shmem_abi->TryAcquireChunkForReading(
                req.chunks_to_move()[i].page(),
                req.chunks_to_move()[i].chunk());
            shmem_abi->ReleaseChunkAsFree(std::move(chunk));
          }
        }));

    // Abort the first session. This should resolve the two chunks committed up
    // to this point to an invalid target buffer (ID 0). They will remain
    // buffered until bound to an endpoint (if InitialBindingState::kUnbound).
    arbiter_->AbortStartupTracingForReservation(kTargetBufferReservationId1);

    // Destroy a writer that was created before the abort. This should not cause
    // crashes.
    EXPECT_CALL(mock_producer_endpoint_,
                UnregisterTraceWriter(writer2->writer_id()))
        .Times(Between(0, 1));  // Depending on `initial_state`.
    writer2.reset();

    // Bind to producer endpoint if unbound. The trace writer should not be
    // registered as its target buffer is invalid. Since no startup sessions are
    // active anymore, the arbiter should be fully bound. The commit data
    // request is flushed.
    EnsureArbiterBoundToEndpoint(initial_state);
    EXPECT_TRUE(IsArbiterFullyBound());

    // SMB should be free again, as no writer holds on to any chunk anymore.
    for (size_t i = 0; i < shmem_abi->num_pages(); i++)
      EXPECT_TRUE(shmem_abi->is_page_free(i));

    // Write another packet into another chunk and commit it. It should be sent
    // to the arbiter with invalid target buffer (ID 0).
    {
      auto packet = writer->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke(
            [shmem_abi](const CommitDataRequest& req,
                        MockProducerEndpoint::CommitDataCallback callback) {
              ASSERT_EQ(1, req.chunks_to_move_size());
              EXPECT_EQ(0u, req.chunks_to_move()[0].target_buffer());
              SharedMemoryABI::Chunk chunk =
                  shmem_abi->TryAcquireChunkForReading(
                      req.chunks_to_move()[0].page(),
                      req.chunks_to_move()[0].chunk());
              shmem_abi->ReleaseChunkAsFree(std::move(chunk));
              callback();
            }));
    bool flush_completed = false;
    writer->Flush([&flush_completed] { flush_completed = true; });
    EXPECT_TRUE(flush_completed);

    // Creating a new startup writer for the same buffer does not cause it to
    // register.
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
    std::unique_ptr<TraceWriter> writer1b =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);

    // And a commit on this new writer should again be flushed to the invalid
    // target buffer.
    {
      auto packet = writer1b->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke(
            [shmem_abi](const CommitDataRequest& req,
                        MockProducerEndpoint::CommitDataCallback callback) {
              ASSERT_EQ(1, req.chunks_to_move_size());
              EXPECT_EQ(0u, req.chunks_to_move()[0].target_buffer());
              SharedMemoryABI::Chunk chunk =
                  shmem_abi->TryAcquireChunkForReading(
                      req.chunks_to_move()[0].page(),
                      req.chunks_to_move()[0].chunk());
              shmem_abi->ReleaseChunkAsFree(std::move(chunk));
              callback();
            }));
    flush_completed = false;
    writer1b->Flush([&flush_completed] { flush_completed = true; });
    EXPECT_TRUE(flush_completed);

    // Create another startup writer for another target buffer, which puts the
    // arbiter back into unbound state.
    std::unique_ptr<TraceWriter> writer3 =
        arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId2);
    EXPECT_FALSE(IsArbiterFullyBound());

    // Write a chunk into both writers. Both should be queued up into the next
    // commit request.
    {
      auto packet = writer->NewTracePacket();
      packet->set_for_testing()->set_str("foo");
    }
    writer->Flush();
    {
      auto packet = writer3->NewTracePacket();
      packet->set_for_testing()->set_str("bar");
    }
    flush_completed = false;
    writer3->Flush([&flush_completed] { flush_completed = true; });

    // Destroy the first trace writer, which should cause the arbiter to post a
    // task to unregister it.
    auto checkpoint_writer =
        task_runner_->CreateCheckpoint("writer_unregistered");
    EXPECT_CALL(mock_producer_endpoint_,
                UnregisterTraceWriter(writer->writer_id()))
        .WillOnce(testing::InvokeWithoutArgs(checkpoint_writer));
    writer.reset();
    task_runner_->RunUntilCheckpoint("writer_unregistered", 5000);

    // Abort the second session. Its commits should now also be associated with
    // target buffer 0, and both writers' commits flushed.
    EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
    EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
        .WillOnce(Invoke(
            [shmem_abi](const CommitDataRequest& req,
                        MockProducerEndpoint::CommitDataCallback callback) {
              ASSERT_EQ(2, req.chunks_to_move_size());
              for (size_t i = 0; i < 2; i++) {
                EXPECT_EQ(0u, req.chunks_to_move()[i].target_buffer());
                SharedMemoryABI::Chunk chunk =
                    shmem_abi->TryAcquireChunkForReading(
                        req.chunks_to_move()[i].page(),
                        req.chunks_to_move()[i].chunk());
                shmem_abi->ReleaseChunkAsFree(std::move(chunk));
              }
              callback();
            }));

    arbiter_->AbortStartupTracingForReservation(kTargetBufferReservationId2);
    EXPECT_TRUE(IsArbiterFullyBound());
    EXPECT_TRUE(flush_completed);

    // SMB should be free again, as no writer holds on to any chunk anymore.
    for (size_t i = 0; i < shmem_abi->num_pages(); i++)
      EXPECT_TRUE(shmem_abi->is_page_free(i));
  }
};

INSTANTIATE_TEST_SUITE_P(PageSize,
                         SharedMemoryArbiterImplStartupTracingTest,
                         ::testing::ValuesIn(kPageSizes));

TEST_P(SharedMemoryArbiterImplStartupTracingTest, StartupTracingUnbound) {
  TestStartupTracing(InitialBindingState::kUnbound);
}

TEST_P(SharedMemoryArbiterImplStartupTracingTest, StartupTracingBound) {
  TestStartupTracing(InitialBindingState::kBound);
}

TEST_P(SharedMemoryArbiterImplStartupTracingTest,
       AbortStartupTracingForReservationUnbound) {
  TestAbortStartupTracingForReservation(InitialBindingState::kUnbound);
}

TEST_P(SharedMemoryArbiterImplStartupTracingTest,
       AbortStartupTracingForReservationBound) {
  TestAbortStartupTracingForReservation(InitialBindingState::kBound);
}

// TODO(primiano): add multi-threaded tests.

}  // namespace perfetto
