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