blob: 7bdeff7fab6190cc76251e9ba459a0aff551694d [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 <gtest/gtest.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <src/developer/tracing/lib/test_utils/spawn_and_wait.h>
#include <src/lib/fxl/command_line.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/test/test_settings.h>
#include <trace-reader/file_reader.h>
#include "garnet/lib/perfmon/controller.h"
const char kTracePath[] = "/bin/trace";
const char kDurationArg[] = "--duration=1";
// Note: /data is no longer large enough in qemu sessions
const char kOutputFile[] = "/tmp/test-trace.fxt";
#if defined(__x86_64__)
const char kCategoriesArg[] =
"--categories=cpu:fixed:instructions_retired,cpu:tally";
const char kCategoryName[] = "cpu:perf";
const char kTestEventName[] = "instructions_retired";
#else
#error "unsupported architecture"
#endif
TEST(CpuperfProvider, IntegrationTest) {
zx::job job;
ASSERT_EQ(zx::job::create(*zx::job::default_job(), 0, &job), ZX_OK);
zx::process child;
std::vector<std::string> argv{
kTracePath, "record", "--binary", kDurationArg, kCategoriesArg,
std::string("--output-file=") + kOutputFile};
ASSERT_EQ(SpawnProgram(job, argv, ZX_HANDLE_INVALID, &child), ZX_OK);
int return_code;
ASSERT_EQ(WaitAndGetExitCode(argv[0], child, &return_code), ZX_OK);
EXPECT_EQ(return_code, 0);
size_t record_count = 0;
size_t instructions_retired_count = 0;
auto record_consumer = [&record_count, &instructions_retired_count](trace::Record record) {
++record_count;
if (record.type() == trace::RecordType::kEvent) {
const trace::Record::Event& event = record.GetEvent();
if (event.type() == trace::EventType::kCounter &&
event.category == kCategoryName &&
event.name == kTestEventName) {
++instructions_retired_count;
}
}
};
bool got_error = false;
auto error_handler = [&got_error](fbl::String error) {
FXL_LOG(ERROR) << "While reading records got error: " << error.c_str();
got_error = true;
};
std::unique_ptr<trace::FileReader> reader;
ASSERT_TRUE(trace::FileReader::Create(kOutputFile,
std::move(record_consumer),
std::move(error_handler), &reader));
reader->ReadFile();
ASSERT_FALSE(got_error);
FXL_LOG(INFO) << "Got " << record_count << " records, "
<< instructions_retired_count << " instructions";
ASSERT_GT(instructions_retired_count, 0u);
}
// Provide our own main so that --verbose,etc. are recognized.
int main(int argc, char** argv) {
fxl::CommandLine cl = fxl::CommandLineFromArgcArgv(argc, argv);
if (!fxl::SetTestSettings(cl))
return EXIT_FAILURE;
if (!perfmon::Controller::IsSupported()) {
FXL_LOG(INFO) << "Exiting, perfmon device not supported";
return 0;
}
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}