1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "perfetto/ext/base/file_utils.h"
18 #include "perfetto/ext/base/scoped_file.h"
19 #include "perfetto/ext/base/utils.h"
20 #include "perfetto/trace_processor/read_trace.h"
21
22 #include "src/base/test/utils.h"
23 #include "test/gtest_and_gmock.h"
24
25 #include "protos/perfetto/trace/trace.pbzero.h"
26 #include "protos/perfetto/trace/trace_packet.pbzero.h"
27
28 namespace perfetto {
29 namespace trace_processor {
30 namespace {
31
OpenTestTrace(const std::string & path)32 base::ScopedFstream OpenTestTrace(const std::string& path) {
33 std::string full_path = base::GetTestDataPath(path);
34 EXPECT_TRUE(base::FileExists(full_path)) << full_path;
35 return base::ScopedFstream(fopen(full_path.c_str(), "rb"));
36 }
37
ReadAllData(const base::ScopedFstream & f)38 std::vector<uint8_t> ReadAllData(const base::ScopedFstream& f) {
39 std::vector<uint8_t> raw_trace;
40 while (!feof(*f)) {
41 uint8_t buf[4096];
42 auto rsize =
43 fread(reinterpret_cast<char*>(buf), 1, base::ArraySize(buf), *f);
44 raw_trace.insert(raw_trace.end(), buf, buf + rsize);
45 }
46 return raw_trace;
47 }
48
TEST(ReadTraceIntegrationTest,CompressedTrace)49 TEST(ReadTraceIntegrationTest, CompressedTrace) {
50 base::ScopedFstream f = OpenTestTrace("test/data/compressed.pb");
51 std::vector<uint8_t> raw_trace = ReadAllData(f);
52
53 std::vector<uint8_t> decompressed;
54 decompressed.reserve(raw_trace.size());
55
56 util::Status status = trace_processor::DecompressTrace(
57 raw_trace.data(), raw_trace.size(), &decompressed);
58 ASSERT_TRUE(status.ok());
59
60 protos::pbzero::Trace::Decoder decoder(decompressed.data(),
61 decompressed.size());
62 uint32_t packet_count = 0;
63 for (auto it = decoder.packet(); it; ++it) {
64 protos::pbzero::TracePacket::Decoder packet(*it);
65 ASSERT_FALSE(packet.has_compressed_packets());
66 ++packet_count;
67 }
68 ASSERT_EQ(packet_count, 2412u);
69 }
70
TEST(ReadTraceIntegrationTest,NonProtobufShouldNotDecompress)71 TEST(ReadTraceIntegrationTest, NonProtobufShouldNotDecompress) {
72 base::ScopedFstream f = OpenTestTrace("test/data/unsorted_trace.json");
73 std::vector<uint8_t> raw_trace = ReadAllData(f);
74
75 std::vector<uint8_t> decompressed;
76 util::Status status = trace_processor::DecompressTrace(
77 raw_trace.data(), raw_trace.size(), &decompressed);
78 ASSERT_FALSE(status.ok());
79 }
80
TEST(ReadTraceIntegrationTest,OuterGzipDecompressTrace)81 TEST(ReadTraceIntegrationTest, OuterGzipDecompressTrace) {
82 base::ScopedFstream f =
83 OpenTestTrace("test/data/example_android_trace_30s.pb.gz");
84 std::vector<uint8_t> raw_compressed_trace = ReadAllData(f);
85
86 std::vector<uint8_t> decompressed;
87 util::Status status = trace_processor::DecompressTrace(
88 raw_compressed_trace.data(), raw_compressed_trace.size(), &decompressed);
89 ASSERT_TRUE(status.ok());
90
91 base::ScopedFstream u =
92 OpenTestTrace("test/data/example_android_trace_30s.pb");
93 std::vector<uint8_t> raw_trace = ReadAllData(u);
94
95 ASSERT_EQ(decompressed.size(), raw_trace.size());
96 ASSERT_EQ(decompressed, raw_trace);
97 }
98
TEST(ReadTraceIntegrationTest,DoubleGzipDecompressTrace)99 TEST(ReadTraceIntegrationTest, DoubleGzipDecompressTrace) {
100 base::ScopedFstream f = OpenTestTrace("test/data/compressed.pb.gz");
101 std::vector<uint8_t> raw_compressed_trace = ReadAllData(f);
102
103 std::vector<uint8_t> decompressed;
104 util::Status status = trace_processor::DecompressTrace(
105 raw_compressed_trace.data(), raw_compressed_trace.size(), &decompressed);
106 ASSERT_TRUE(status.ok());
107
108 protos::pbzero::Trace::Decoder decoder(decompressed.data(),
109 decompressed.size());
110 uint32_t packet_count = 0;
111 for (auto it = decoder.packet(); it; ++it) {
112 protos::pbzero::TracePacket::Decoder packet(*it);
113 ASSERT_FALSE(packet.has_compressed_packets());
114 ++packet_count;
115 }
116 ASSERT_EQ(packet_count, 2412u);
117 }
118
119 } // namespace
120 } // namespace trace_processor
121 } // namespace perfetto
122