1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <trace-reader/reader.h> 6 7#include <stdint.h> 8 9#include <fbl/algorithm.h> 10#include <fbl/vector.h> 11#include <unittest/unittest.h> 12 13namespace { 14 15template <typename T> 16uint64_t ToWord(const T& value) { 17 return *reinterpret_cast<const uint64_t*>(&value); 18} 19 20trace::TraceReader::RecordConsumer MakeRecordConsumer( 21 fbl::Vector<trace::Record>* out_records) { 22 return [out_records](trace::Record record) { 23 out_records->push_back(fbl::move(record)); 24 }; 25} 26 27trace::TraceReader::ErrorHandler MakeErrorHandler(fbl::String* out_error) { 28 return [out_error](fbl::String error) { 29 *out_error = fbl::move(error); 30 }; 31} 32 33bool empty_chunk_test() { 34 BEGIN_TEST; 35 36 uint64_t value; 37 int64_t int64_value; 38 double double_value; 39 fbl::StringPiece string_value; 40 trace::Chunk subchunk; 41 42 trace::Chunk empty; 43 EXPECT_EQ(0u, empty.remaining_words()); 44 45 EXPECT_FALSE(empty.ReadUint64(&value)); 46 47 EXPECT_FALSE(empty.ReadInt64(&int64_value)); 48 49 EXPECT_FALSE(empty.ReadDouble(&double_value)); 50 51 EXPECT_TRUE(empty.ReadString(0u, &string_value)); 52 EXPECT_TRUE(string_value.empty()); 53 EXPECT_FALSE(empty.ReadString(1u, &string_value)); 54 55 EXPECT_TRUE(empty.ReadChunk(0u, &subchunk)); 56 EXPECT_EQ(0u, subchunk.remaining_words()); 57 EXPECT_FALSE(empty.ReadChunk(1u, &subchunk)); 58 59 END_TEST; 60} 61 62bool non_empty_chunk_test() { 63 BEGIN_TEST; 64 65 uint64_t value; 66 int64_t int64_value; 67 double double_value; 68 fbl::StringPiece string_value; 69 trace::Chunk subchunk; 70 71 uint64_t kData[] = { 72 // uint64 values 73 0, 74 UINT64_MAX, 75 // int64 values 76 ToWord(INT64_MIN), 77 ToWord(INT64_MAX), 78 // double values 79 ToWord(1.5), 80 ToWord(-3.14), 81 // string values (will be filled in) 82 0, 83 0, 84 // sub-chunk values 85 123, 86 456, 87 // more stuff beyond sub-chunk 88 789, 89 }; 90 memcpy(kData + 6, "Hello World!----", 16); 91 92 trace::Chunk chunk(kData, fbl::count_of(kData)); 93 EXPECT_EQ(fbl::count_of(kData), chunk.remaining_words()); 94 95 EXPECT_TRUE(chunk.ReadUint64(&value)); 96 EXPECT_EQ(0, value); 97 EXPECT_EQ(10u, chunk.remaining_words()); 98 99 EXPECT_TRUE(chunk.ReadUint64(&value)); 100 EXPECT_EQ(UINT64_MAX, value); 101 EXPECT_EQ(9u, chunk.remaining_words()); 102 103 EXPECT_TRUE(chunk.ReadInt64(&int64_value)); 104 EXPECT_EQ(INT64_MIN, int64_value); 105 EXPECT_EQ(8u, chunk.remaining_words()); 106 107 EXPECT_TRUE(chunk.ReadInt64(&int64_value)); 108 EXPECT_EQ(INT64_MAX, int64_value); 109 EXPECT_EQ(7u, chunk.remaining_words()); 110 111 EXPECT_TRUE(chunk.ReadDouble(&double_value)); 112 EXPECT_EQ(1.5, double_value); 113 EXPECT_EQ(6u, chunk.remaining_words()); 114 115 EXPECT_TRUE(chunk.ReadDouble(&double_value)); 116 EXPECT_EQ(-3.14, double_value); 117 EXPECT_EQ(5u, chunk.remaining_words()); 118 119 EXPECT_TRUE(chunk.ReadString(0u, &string_value)); 120 EXPECT_TRUE(string_value.empty()); 121 EXPECT_EQ(5u, chunk.remaining_words()); 122 123 EXPECT_TRUE(chunk.ReadString(12u, &string_value)); 124 EXPECT_EQ(12u, string_value.length()); 125 EXPECT_EQ(reinterpret_cast<const char*>(kData + 6), string_value.data()); 126 EXPECT_TRUE(fbl::String(string_value) == "Hello World!"); 127 EXPECT_EQ(3u, chunk.remaining_words()); 128 129 EXPECT_TRUE(chunk.ReadChunk(2u, &subchunk)); 130 EXPECT_EQ(2u, subchunk.remaining_words()); 131 EXPECT_TRUE(subchunk.ReadUint64(&value)); 132 133 EXPECT_EQ(123, value); 134 EXPECT_EQ(1u, subchunk.remaining_words()); 135 136 EXPECT_TRUE(chunk.ReadUint64(&value)); 137 EXPECT_EQ(789, value); 138 EXPECT_EQ(0u, chunk.remaining_words()); 139 140 EXPECT_TRUE(subchunk.ReadUint64(&value)); 141 EXPECT_EQ(456, value); 142 EXPECT_EQ(0u, subchunk.remaining_words()); 143 144 EXPECT_FALSE(subchunk.ReadUint64(&value)); 145 EXPECT_FALSE(chunk.ReadUint64(&value)); 146 147 END_TEST; 148} 149 150bool initial_state_test() { 151 BEGIN_TEST; 152 153 fbl::Vector<trace::Record> records; 154 fbl::String error; 155 trace::TraceReader reader(MakeRecordConsumer(&records), MakeErrorHandler(&error)); 156 157 EXPECT_EQ(0, reader.current_provider_id()); 158 EXPECT_TRUE(reader.current_provider_name() == ""); 159 EXPECT_TRUE(reader.GetProviderName(0) == ""); 160 EXPECT_EQ(0, records.size()); 161 EXPECT_TRUE(error.empty()); 162 163 END_TEST; 164} 165 166bool empty_buffer_test() { 167 BEGIN_TEST; 168 169 fbl::Vector<trace::Record> records; 170 fbl::String error; 171 trace::TraceReader reader(MakeRecordConsumer(&records), MakeErrorHandler(&error)); 172 173 trace::Chunk empty; 174 EXPECT_TRUE(reader.ReadRecords(empty)); 175 EXPECT_EQ(0, records.size()); 176 EXPECT_TRUE(error.empty()); 177 178 END_TEST; 179} 180 181// NOTE: Most of the reader is covered by the libtrace tests. 182 183} // namespace 184 185BEGIN_TEST_CASE(reader_tests) 186RUN_TEST(empty_chunk_test) 187RUN_TEST(non_empty_chunk_test) 188RUN_TEST(initial_state_test) 189RUN_TEST(empty_buffer_test) 190END_TEST_CASE(reader_tests) 191