blob: 94dce83db0c2fdacfd39e4e1f3419c8820930e91 [file] [log] [blame]
// Copyright 2018 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 "trace-test-utils/compare_records.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <trace-reader/reader.h>
#include <trace-reader/reader_internal.h>
#include "trace-test-utils/read_records.h"
#include "trace-test-utils/squelch.h"
namespace trace_testing {
bool CompareRecords(const fbl::Vector<trace::Record>& records, size_t start_record,
size_t max_num_records, const char* expected) {
// Strip out timestamps and other varying data that is not controlled by
// the tests.
std::unique_ptr<Squelcher> squelcher = Squelcher::Create({
{"[0-9]+/[0-9]+", "<>"},
{"koid\\([0-9]+\\)", "koid(<>)"},
{"koid: [0-9]+", "koid: <>"},
{"ts: [0-9]+", "ts: <>"},
{"end_ts: [0-9]+", "end_ts: <>"},
{"0x[0-9a-f]+", "<>"},
});
ZX_DEBUG_ASSERT(squelcher);
fbl::StringBuffer<16384u> buf;
size_t num_recs = 0;
for (size_t i = start_record; i < records.size(); ++i) {
if (num_recs == max_num_records)
break;
const auto& record = records[i];
fbl::String from_str = record.ToString();
fbl::String to_str = squelcher->Squelch(from_str.c_str());
buf.Append(to_str);
buf.Append('\n');
++num_recs;
}
if (strcmp(buf.c_str(), expected) != 0) {
fprintf(stderr, "Records do not match expected contents:\n");
fprintf(stderr, "Buffer:\n%s\n", buf.c_str());
fprintf(stderr, "Expected:\n%s\n", expected);
return false;
}
return true;
}
bool ComparePartialBuffer(const fbl::Vector<trace::Record>& records, size_t max_num_records,
const char* expected, size_t* out_leading_to_skip) {
// A valid buffer should at least have the initialization record.
if (records.size() == 0) {
fprintf(stderr, "expected an initialization record\n");
return false;
}
if (records[0].type() != trace::RecordType::kInitialization) {
fprintf(stderr, "expected initialization record\n");
return false;
}
// Sanity check the recorded ticks/seconds.
if (records[0].GetInitialization().ticks_per_second !=
static_cast<trace_ticks_t>(zx_ticks_per_second())) {
fprintf(stderr, "Bad ticks/second field in initialization record\n");
return false;
}
// Done with this record, skip it in further analysis.
size_t skip_count = 1;
if (!CompareRecords(records, skip_count, max_num_records, expected)) {
// Diagnostic messages already printed.
return false;
}
if (out_leading_to_skip) {
*out_leading_to_skip = skip_count;
}
return true;
}
bool CompareBuffer(const fbl::Vector<trace::Record>& records, const char* expected) {
return ComparePartialBuffer(records, SIZE_MAX, expected, nullptr);
}
} // namespace trace_testing