blob: 334696e7432847b6657a587e3178abadb1682311 [file] [log] [blame]
Austin Schuh25356e22019-09-11 19:27:07 -07001#include "aos/ipc_lib/index.h"
2
Stephan Pleines682928d2024-05-31 20:43:48 -07003#include <ostream>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "glog/logging.h"
Austin Schuh60e77942022-05-16 17:48:24 -07006#include "gtest/gtest.h"
Austin Schuh25356e22019-09-11 19:27:07 -07007
Stephan Pleinesf63bde82024-01-13 15:59:33 -08008namespace aos::ipc_lib::testing {
Austin Schuh25356e22019-09-11 19:27:07 -07009
10class QueueIndexTest : public ::testing::Test {
11 protected:
12 uint32_t GetIndex(const QueueIndex &index) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070013 LOG(INFO) << "Index, count: " << std::hex << index.index_ << ", "
14 << index.count_;
Austin Schuh25356e22019-09-11 19:27:07 -070015 return index.index();
16 }
17
18 QueueIndex Make(uint32_t index, uint32_t count) {
19 return QueueIndex(index, count);
20 }
21};
22
23// Tests that an invalid index is invalid.
24TEST_F(QueueIndexTest, TestValid) {
25 QueueIndex invalid = QueueIndex::Invalid();
26
27 EXPECT_EQ(0xffffffff, GetIndex(invalid));
28 EXPECT_FALSE(invalid.valid());
29
30 QueueIndex valid = Make(5, 7);
31
32 EXPECT_TRUE(valid.valid());
33}
34
35// Tests that the max index function returns the max index as expected.
36TEST_F(QueueIndexTest, TestMaxIndex) {
37 EXPECT_EQ(QueueIndex::MaxIndex(12u, 4u), 12u);
38 EXPECT_EQ(QueueIndex::MaxIndex(13u, 4u), 12u);
39 EXPECT_EQ(QueueIndex::MaxIndex(14u, 4u), 12u);
40 EXPECT_EQ(QueueIndex::MaxIndex(15u, 4u), 12u);
41 EXPECT_EQ(QueueIndex::MaxIndex(16u, 4u), 16u);
42}
43
44// Tests that incrementing an index works as expected.
45TEST_F(QueueIndexTest, TestIncrement) {
46 QueueIndex zero = Make(0, 3);
47
48 EXPECT_EQ(GetIndex(zero), 0u);
49
50 QueueIndex one = zero.Increment();
51 EXPECT_EQ(GetIndex(one), 1u);
52
53 // Try it with a base 3. Apparently 3 fits exactly.
54 {
55 QueueIndex two_below = Make(QueueIndex::MaxIndex(0xffffffffu, 3u) - 2, 3);
56 EXPECT_EQ(GetIndex(two_below), 0xfffffffdu);
57
58 QueueIndex one_below = two_below.Increment();
59 EXPECT_EQ(GetIndex(one_below), 0xfffffffeu);
60
61 QueueIndex wrapped = one_below.Increment();
62 EXPECT_EQ(GetIndex(wrapped), 0);
63
64 EXPECT_EQ(wrapped, zero);
65 }
66
67 // Now try it with base 4. Should still work.
68 {
69 QueueIndex two_below = Make(QueueIndex::MaxIndex(0xffffffffu, 4u) - 2, 4);
70 EXPECT_EQ(GetIndex(two_below), 0xfffffffau);
71
72 QueueIndex one_below = two_below.Increment();
73 EXPECT_EQ(GetIndex(one_below), 0xfffffffbu);
74
75 QueueIndex wrapped = one_below.Increment();
76 EXPECT_EQ(GetIndex(wrapped), 0);
77 }
78}
79
80// Tests that decrementing and incrementing again an index works as expected.
81TEST_F(QueueIndexTest, TestDecrement) {
82 {
83 QueueIndex zero = Make(0, 3);
84 EXPECT_EQ(GetIndex(zero), 0x00000000u);
85
86 QueueIndex negative10 = zero.DecrementBy(10);
87 EXPECT_EQ(GetIndex(negative10), 0xffffffff - 10);
88
89 EXPECT_EQ(zero, negative10.IncrementBy(10));
90 }
91 {
92 QueueIndex zero = Make(0, 4);
93 EXPECT_EQ(GetIndex(zero), 0x00000000u);
94
95 QueueIndex negative10 = zero.DecrementBy(10);
96 EXPECT_EQ(GetIndex(negative10), 0xfffffffc - 10);
97
98 EXPECT_EQ(zero, negative10.IncrementBy(10));
99 }
100
101 {
102 QueueIndex five = Make(5, 3);
103 EXPECT_EQ(GetIndex(five), 5u);
104
105 QueueIndex negative10 = five.DecrementBy(10);
106 EXPECT_EQ(GetIndex(negative10), 0xffffffff - 5);
107
108 EXPECT_EQ(five, negative10.IncrementBy(10));
109 }
110 {
111 QueueIndex five = Make(5, 4);
112 EXPECT_EQ(GetIndex(five), 5u);
113
114 QueueIndex negative10 = five.DecrementBy(10);
115 EXPECT_EQ(GetIndex(negative10), 0xfffffffc - 5);
116
117 EXPECT_EQ(five, negative10.IncrementBy(10));
118 }
119}
120
121// Tests that an invalid index is invalid, and a valid one is valid.
122TEST(IndexTest, TestInvalid) {
123 EXPECT_FALSE(Index::Invalid().valid());
124
125 EXPECT_TRUE(Index(0, 0).valid());
126}
127
128// Tests that we get back the two indices as expected.
129TEST(IndexTest, TestRecoverIndices) {
130 QueueIndex five = QueueIndex::Zero(100).IncrementBy(5);
131 Index index(five, 11);
132 EXPECT_EQ(index.queue_index(), 5);
133 EXPECT_EQ(index.message_index(), 11);
134}
135
Austin Schuh83cbb1e2023-06-23 12:59:02 -0700136#if AOS_QUEUE_ATOMIC_SIZE == 64
137// Tests that the 64 bit plausible has sane behavior.
138TEST(IndexTest, TestPlausible) {
139 QueueIndex five = QueueIndex::Zero(100).IncrementBy(5);
140 QueueIndex ffff = QueueIndex::Zero(100).IncrementBy(0xffff);
141
142 // Tests some various combinations of indices.
143 for (int i = 0; i < 100; ++i) {
144 Index index(five, i);
145 EXPECT_EQ(index.queue_index(), 5 + i * 0x10000);
146
147 EXPECT_TRUE(index.IsPlausible(five));
148
149 EXPECT_EQ(index.message_index(), i);
150
151 five = five.IncrementBy(0x10000);
152 }
153
154 // Tests that a queue index with a value of 0xffff doesn't match an invalid
155 // index.
156 for (int i = 0; i < 100; ++i) {
157 Index index(ffff, i);
158 EXPECT_EQ(index.queue_index(), 0xffff);
159
160 EXPECT_TRUE(index.IsPlausible(ffff));
161 EXPECT_FALSE(index.IsPlausible(QueueIndex::Invalid()));
162
163 EXPECT_EQ(index.message_index(), i);
164 }
165}
166#else
Austin Schuh25356e22019-09-11 19:27:07 -0700167// Tests that Plausible behaves.
168TEST(IndexTest, TestPlausible) {
169 QueueIndex five = QueueIndex::Zero(100).IncrementBy(5);
170 QueueIndex ffff = QueueIndex::Zero(100).IncrementBy(0xffff);
171
172 // Tests that if five has wrapped, we still return plausible.
173 for (int i = 0; i < 100; ++i) {
174 Index index(five, i);
175 EXPECT_EQ(index.queue_index(), 5);
176
177 EXPECT_TRUE(index.IsPlausible(five));
178
179 EXPECT_EQ(index.message_index(), i);
180
181 five = five.IncrementBy(0x10000);
182 }
183
184 // Tests that a queue index with a value of 0xffff doesn't match an invalid
185 // index.
186 for (int i = 0; i < 100; ++i) {
187 Index index(ffff, i);
188 EXPECT_EQ(index.queue_index(), 0xffff);
189
190 EXPECT_TRUE(index.IsPlausible(ffff));
191 EXPECT_FALSE(index.IsPlausible(QueueIndex::Invalid()));
192
193 EXPECT_EQ(index.message_index(), i);
194 }
195}
Austin Schuh83cbb1e2023-06-23 12:59:02 -0700196#endif
197
198// Tests that the max message size makes sense.
199TEST(IndexTest, TestMaxMessages) {
200#if AOS_QUEUE_ATOMIC_SIZE == 64
201 EXPECT_EQ(Index::MaxMessages(), 0xfffffffe);
202#else
203 EXPECT_EQ(Index::MaxMessages(), 0xfffe);
204#endif
205}
Austin Schuh25356e22019-09-11 19:27:07 -0700206
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800207} // namespace aos::ipc_lib::testing