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