blob: c25bbb508144b4754a4e1e1a7e3ae4904e2b0e5d [file] [log] [blame]
// Copyright 2020 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 "../session.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/trace-provider/provider.h>
#include <lib/trace/event.h>
#include <zxtest/zxtest.h>
namespace trace {
namespace {
static constexpr size_t kBufferSize = 65535;
static constexpr size_t kFifoCount = 4;
static const std::string kAlertName = "alert_name";
static const std::string kAlertNameMin = "a";
static const std::string kAlertNameMax = "alert_name_max";
void CheckAlertNameAndZeroPadding(const std::string& alert_name, const void* p, size_t size) {
const char* pchar = reinterpret_cast<const char*>(p);
for (size_t index = 0; size > 0; --size, ++pchar, ++index) {
if (index >= alert_name.size()) {
ASSERT_EQ(0, *pchar);
continue;
}
ASSERT_EQ(alert_name[index], *pchar);
}
}
// Tests that alerts are send over the fifo.
TEST(SessionTest, AlertSent) {
async::Loop loop{&kAsyncLoopConfigNoAttachToCurrentThread};
zx::vmo buffer;
zx_status_t status = zx::vmo::create(kBufferSize, 0, &buffer);
ASSERT_EQ(ZX_OK, status);
zx::fifo fifo_provider;
zx::fifo fifo_manager;
status = zx::fifo::create(kFifoCount, sizeof(trace_provider_packet_t), 0, &fifo_provider,
&fifo_manager);
ASSERT_EQ(ZX_OK, status);
std::vector<std::string> categories;
categories.push_back("test_category");
internal::Session::InitializeEngine(loop.dispatcher(), TRACE_BUFFERING_MODE_CIRCULAR,
std::move(buffer), std::move(fifo_provider), categories);
// Not started yet.
TRACE_ALERT("test_category", kAlertName.c_str());
trace_provider_packet_t packet;
size_t actual;
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_ERR_SHOULD_WAIT, status);
internal::Session::StartEngine(TRACE_START_CLEAR_ENTIRE_BUFFER);
// No alerts since start.
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_ERR_SHOULD_WAIT, status);
// Alert name neither min nor max length.
TRACE_ALERT("test_category", kAlertName.c_str());
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_OK, status);
ASSERT_EQ(1, actual);
ASSERT_EQ(TRACE_PROVIDER_ALERT, packet.request);
CheckAlertNameAndZeroPadding(
kAlertName, &packet.data16,
sizeof(packet.data16) + sizeof(packet.data32) + sizeof(packet.data64));
// Alert name of min length (1).
TRACE_ALERT("test_category", kAlertNameMin.c_str());
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_OK, status);
ASSERT_EQ(1, actual);
ASSERT_EQ(TRACE_PROVIDER_ALERT, packet.request);
CheckAlertNameAndZeroPadding(
kAlertNameMin, &packet.data16,
sizeof(packet.data16) + sizeof(packet.data32) + sizeof(packet.data64));
// Alert name of max length (14).
TRACE_ALERT("test_category", kAlertNameMax.c_str());
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_OK, status);
ASSERT_EQ(1, actual);
ASSERT_EQ(TRACE_PROVIDER_ALERT, packet.request);
CheckAlertNameAndZeroPadding(
kAlertNameMax, &packet.data16,
sizeof(packet.data16) + sizeof(packet.data32) + sizeof(packet.data64));
// Disabled category.
TRACE_ALERT("other_category", kAlertName.c_str());
status = fifo_manager.read(sizeof(trace_provider_packet_t), &packet, 1, &actual);
ASSERT_EQ(ZX_ERR_SHOULD_WAIT, status);
loop.RunUntilIdle();
loop.Shutdown();
}
} // namespace
} // namespace trace