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
ZlibSupported()49 bool ZlibSupported() {
50 #if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
51 return true;
52 #else
53 return false;
54 #endif
55 }
56
57 class ReadTraceIntegrationTest : public testing::Test {
SetUp()58 void SetUp() override {
59 if (!ZlibSupported()) {
60 GTEST_SKIP() << "Gzip not enabled";
61 }
62 }
63 };
64
TEST_F(ReadTraceIntegrationTest,CompressedTrace)65 TEST_F(ReadTraceIntegrationTest, CompressedTrace) {
66 base::ScopedFstream f = OpenTestTrace("test/data/compressed.pb");
67 std::vector<uint8_t> raw_trace = ReadAllData(f);
68
69 std::vector<uint8_t> decompressed;
70 decompressed.reserve(raw_trace.size());
71
72 util::Status status = trace_processor::DecompressTrace(
73 raw_trace.data(), raw_trace.size(), &decompressed);
74 ASSERT_TRUE(status.ok());
75
76 protos::pbzero::Trace::Decoder decoder(decompressed.data(),
77 decompressed.size());
78 uint32_t packet_count = 0;
79 for (auto it = decoder.packet(); it; ++it) {
80 protos::pbzero::TracePacket::Decoder packet(*it);
81 ASSERT_FALSE(packet.has_compressed_packets());
82 ++packet_count;
83 }
84 ASSERT_EQ(packet_count, 2412u);
85 }
86
TEST_F(ReadTraceIntegrationTest,NonProtobufShouldNotDecompress)87 TEST_F(ReadTraceIntegrationTest, NonProtobufShouldNotDecompress) {
88 base::ScopedFstream f = OpenTestTrace("test/data/unsorted_trace.json");
89 std::vector<uint8_t> raw_trace = ReadAllData(f);
90
91 std::vector<uint8_t> decompressed;
92 util::Status status = trace_processor::DecompressTrace(
93 raw_trace.data(), raw_trace.size(), &decompressed);
94 ASSERT_FALSE(status.ok());
95 }
96
TEST_F(ReadTraceIntegrationTest,OuterGzipDecompressTrace)97 TEST_F(ReadTraceIntegrationTest, OuterGzipDecompressTrace) {
98 base::ScopedFstream f =
99 OpenTestTrace("test/data/example_android_trace_30s.pb.gz");
100 std::vector<uint8_t> raw_compressed_trace = ReadAllData(f);
101
102 std::vector<uint8_t> decompressed;
103 util::Status status = trace_processor::DecompressTrace(
104 raw_compressed_trace.data(), raw_compressed_trace.size(), &decompressed);
105 ASSERT_TRUE(status.ok());
106
107 base::ScopedFstream u =
108 OpenTestTrace("test/data/example_android_trace_30s.pb");
109 std::vector<uint8_t> raw_trace = ReadAllData(u);
110
111 ASSERT_EQ(decompressed.size(), raw_trace.size());
112 ASSERT_EQ(decompressed, raw_trace);
113 }
114
TEST_F(ReadTraceIntegrationTest,DoubleGzipDecompressTrace)115 TEST_F(ReadTraceIntegrationTest, DoubleGzipDecompressTrace) {
116 base::ScopedFstream f = OpenTestTrace("test/data/compressed.pb.gz");
117 std::vector<uint8_t> raw_compressed_trace = ReadAllData(f);
118
119 std::vector<uint8_t> decompressed;
120 util::Status status = trace_processor::DecompressTrace(
121 raw_compressed_trace.data(), raw_compressed_trace.size(), &decompressed);
122 ASSERT_TRUE(status.ok()) << status.message();
123
124 protos::pbzero::Trace::Decoder decoder(decompressed.data(),
125 decompressed.size());
126 uint32_t packet_count = 0;
127 for (auto it = decoder.packet(); it; ++it) {
128 protos::pbzero::TracePacket::Decoder packet(*it);
129 ASSERT_FALSE(packet.has_compressed_packets());
130 ++packet_count;
131 }
132 ASSERT_EQ(packet_count, 2412u);
133 }
134
135 } // namespace
136 } // namespace trace_processor
137 } // namespace perfetto
138