1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/tracing/core/sliced_protobuf_input_stream.h"
#include "gtest/gtest.h"
#include "perfetto/base/utils.h"
namespace perfetto {
namespace {
// The tests below work on slices, that are a (start pointer, size) tuple but
// never dereference the memory in the pointer. Hence, we just use an array of
// integers that is used both to derive N distinct pointers and to keep track
// of N distinct sizes. In other words, the tests below will see Slices of the
// form {start: &kBuf[0], end: &kBuf[0] + kBuf[0]}, and so on. As long as we
// don't dereference those pointers, this int array should be enough.
const int kBufs[]{100, 200, 1024, 0, 10, 0, 1, 1, 7};
TEST(SlicedProtobufInputStreamTest, SingleSlice) {
Slices seq;
seq.emplace_back(&kBufs[0], kBufs[0]);
SlicedProtobufInputStream istr(&seq);
const void* ptr = nullptr;
int size = 0;
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(&kBufs[0], ptr);
ASSERT_EQ(kBufs[0], size);
ASSERT_EQ(kBufs[0], istr.ByteCount());
ASSERT_FALSE(istr.Next(&ptr, &size));
// Backup and read again.
istr.BackUp(10);
ASSERT_EQ(kBufs[0] - 10, istr.ByteCount());
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(reinterpret_cast<const void*>(
reinterpret_cast<uintptr_t>(&kBufs[0]) + kBufs[0] - 10),
ptr);
ASSERT_EQ(10, size);
ASSERT_EQ(kBufs[0], istr.ByteCount());
ASSERT_FALSE(istr.Next(&ptr, &size));
// Backup, skip and read again.
istr.BackUp(50);
ASSERT_EQ(kBufs[0] - 50, istr.ByteCount());
ASSERT_TRUE(istr.Skip(10));
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(reinterpret_cast<const void*>(
reinterpret_cast<uintptr_t>(&kBufs[0]) + kBufs[0] - 50 + 10),
ptr);
ASSERT_EQ(50 - 10, size);
ASSERT_EQ(kBufs[0], istr.ByteCount());
ASSERT_FALSE(istr.Next(&ptr, &size));
}
TEST(SlicedProtobufInputStreamTest, SimpleSequence) {
Slices seq;
for (size_t i = 0; i < base::ArraySize(kBufs); i++)
seq.emplace_back(&kBufs[i], kBufs[i]);
SlicedProtobufInputStream istr(&seq);
int num_bytes = 0;
const void* ptr = nullptr;
int size = 0;
for (size_t i = 0; i < base::ArraySize(kBufs); i++) {
ASSERT_EQ(num_bytes, istr.ByteCount());
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(&kBufs[i], ptr);
ASSERT_EQ(kBufs[i], size);
num_bytes += kBufs[i];
ASSERT_EQ(num_bytes, istr.ByteCount());
}
ASSERT_FALSE(istr.Next(&ptr, &size));
}
TEST(SlicedProtobufInputStreamTest, SequenceWithSkipsAndBackups) {
Slices seq;
for (size_t i = 0; i < base::ArraySize(kBufs); i++)
seq.emplace_back(&kBufs[i], kBufs[i]);
SlicedProtobufInputStream istr(&seq);
ASSERT_TRUE(istr.Skip(99));
ASSERT_EQ(99, istr.ByteCount());
ASSERT_TRUE(istr.Skip(1 + 200 + 1023));
ASSERT_EQ(99 + 1 + 200 + 1023, istr.ByteCount());
ASSERT_TRUE(istr.Skip(1 + 0 + 10 + 0 + 1 + 1 + 3));
ASSERT_EQ(99 + 1 + 200 + 1023 + 1 + 0 + 10 + 0 + 1 + 1 + 3, istr.ByteCount());
const void* ptr = nullptr;
int size = 0;
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(kBufs[8] - 3, size);
ASSERT_EQ(
reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(&kBufs[8]) + 3),
ptr);
istr.BackUp(7 + 1 + 1 + 0 + 10);
ASSERT_TRUE(istr.Next(&ptr, &size));
ASSERT_EQ(&kBufs[4], ptr);
ASSERT_EQ(kBufs[4], size);
}
} // namespace
} // namespace perfetto
|