1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_clock_tree/clock_tree.h"
16
17 #include "pw_preprocessor/util.h"
18 #include "pw_unit_test/framework.h"
19
20 namespace pw::clock_tree {
21 namespace {
22
23 #define INIT_TEST_DATA(test_data, call_data) \
24 test_data.num_expected_calls = PW_ARRAY_SIZE(call_data); \
25 test_data.num_calls = 0; \
26 test_data.data = call_data
27
28 enum class ClockOperation {
29 kAcquire,
30 kRelease,
31 };
32
33 struct clock_divider_test_call_data {
34 uint32_t divider_name;
35 uint32_t divider;
36 ClockOperation op;
37 pw::Status status;
38 };
39
40 struct clock_divider_test_data {
41 uint32_t num_expected_calls;
42 uint32_t num_calls;
43 struct clock_divider_test_call_data* data;
44 };
45
46 template <typename ElementType>
47 class ClockDividerTest : public ClockDividerElement<ElementType> {
48 public:
ClockDividerTest(ElementType & source,uint32_t divider_name,uint32_t divider,struct clock_divider_test_data & test_data)49 constexpr ClockDividerTest(ElementType& source,
50 uint32_t divider_name,
51 uint32_t divider,
52 struct clock_divider_test_data& test_data)
53 : ClockDividerElement<ElementType>(source, divider),
54 divider_name_(divider_name),
55 test_data_(test_data) {}
56
57 private:
ValidateClockAction(ClockOperation op)58 pw::Status ValidateClockAction(ClockOperation op) {
59 pw::Status status = pw::Status::OutOfRange();
60 if (test_data_.num_calls < test_data_.num_expected_calls) {
61 uint32_t i = test_data_.num_calls;
62 EXPECT_EQ(test_data_.data[i].divider_name, divider_name_);
63 EXPECT_EQ(test_data_.data[i].divider, this->divider());
64 EXPECT_EQ(test_data_.data[i].op, op);
65 status = test_data_.data[i].status;
66 }
67 test_data_.num_calls++;
68 return status;
69 }
70
DoEnable()71 pw::Status DoEnable() final {
72 return ValidateClockAction(ClockOperation::kAcquire);
73 }
DoDisable()74 pw::Status DoDisable() final {
75 return ValidateClockAction(ClockOperation::kRelease);
76 }
77
78 uint32_t divider_name_;
79 struct clock_divider_test_data& test_data_;
80 };
81
82 using ClockDividerTestBlocking = ClockDividerTest<ElementBlocking>;
83 using ClockDividerTestNonBlocking =
84 ClockDividerTest<ElementNonBlockingMightFail>;
85
86 template <typename ElementType>
87 class ClockDividerNoDoDisableTest : public ClockDividerElement<ElementType> {
88 public:
ClockDividerNoDoDisableTest(ElementType & source,uint32_t divider_name,uint32_t divider,struct clock_divider_test_data & test_data)89 constexpr ClockDividerNoDoDisableTest(
90 ElementType& source,
91 uint32_t divider_name,
92 uint32_t divider,
93 struct clock_divider_test_data& test_data)
94 : ClockDividerElement<ElementType>(source, divider),
95 divider_name_(divider_name),
96 test_data_(test_data) {}
97
98 private:
ValidateClockAction(ClockOperation op)99 pw::Status ValidateClockAction(ClockOperation op) {
100 pw::Status status = pw::Status::OutOfRange();
101 if (test_data_.num_calls < test_data_.num_expected_calls) {
102 uint32_t i = test_data_.num_calls;
103 EXPECT_EQ(test_data_.data[i].divider_name, divider_name_);
104 EXPECT_EQ(test_data_.data[i].divider, this->divider());
105 EXPECT_EQ(test_data_.data[i].op, op);
106 status = test_data_.data[i].status;
107 }
108 test_data_.num_calls++;
109 return status;
110 }
111
DoEnable()112 pw::Status DoEnable() final {
113 return ValidateClockAction(ClockOperation::kAcquire);
114 }
115
116 uint32_t divider_name_;
117 struct clock_divider_test_data& test_data_;
118 };
119 using ClockDividerNoDoDisableTestBlocking =
120 ClockDividerNoDoDisableTest<ElementBlocking>;
121 using ClockDividerNoDoDisableTestNonBlocking =
122 ClockDividerNoDoDisableTest<ElementNonBlockingMightFail>;
123
124 struct clock_selector_test_call_data {
125 uint32_t selector;
126 uint32_t value;
127 ClockOperation op;
128 pw::Status status;
129 };
130
131 struct clock_selector_test_data {
132 uint32_t num_expected_calls;
133 uint32_t num_calls;
134 struct clock_selector_test_call_data* data;
135 };
136
137 template <typename ElementType>
138 class ClockSelectorTest : public DependentElement<ElementType> {
139 public:
ClockSelectorTest(ElementType & source,uint32_t selector,uint32_t selector_enable,uint32_t selector_disable,struct clock_selector_test_data & test_data)140 constexpr ClockSelectorTest(ElementType& source,
141 uint32_t selector,
142 uint32_t selector_enable,
143 uint32_t selector_disable,
144 struct clock_selector_test_data& test_data)
145 : DependentElement<ElementType>(source),
146 selector_(selector),
147 selector_enable_(selector_enable),
148 selector_disable_(selector_disable),
149 test_data_(test_data) {}
150
SetSource(ElementType & new_source,uint32_t new_selector_enable,uint32_t new_selector_disable,bool permit_change_if_in_use)151 pw::Status SetSource(ElementType& new_source,
152 uint32_t new_selector_enable,
153 uint32_t new_selector_disable,
154 bool permit_change_if_in_use) {
155 // Store a copy of the current `selector_enable_` variable in case
156 // that the update fails, since we need to update `selector_enable_`
157 // to its new value, since `UpdateSource` might call the `DoEnable`
158 // member function.
159 uint32_t old_selector_enable = selector_enable_;
160 selector_enable_ = new_selector_enable;
161 pw::Status status = this->UpdateSource(new_source, permit_change_if_in_use);
162 if (status.ok()) {
163 selector_disable_ = new_selector_disable;
164 } else {
165 // Restore the old selector value.
166 selector_enable_ = old_selector_enable;
167 }
168
169 return status;
170 }
171
172 private:
ValidateClockAction(ClockOperation op)173 pw::Status ValidateClockAction(ClockOperation op) {
174 pw::Status status = pw::Status::OutOfRange();
175 if (test_data_.num_calls < test_data_.num_expected_calls) {
176 uint32_t i = test_data_.num_calls;
177 uint32_t value = (op == ClockOperation::kAcquire) ? selector_enable_
178 : selector_disable_;
179 EXPECT_EQ(test_data_.data[i].selector, selector_);
180 EXPECT_EQ(test_data_.data[i].value, value);
181 EXPECT_EQ(test_data_.data[i].op, op);
182 status = test_data_.data[i].status;
183 }
184 test_data_.num_calls++;
185 return status;
186 }
DoEnable()187 pw::Status DoEnable() final {
188 return ValidateClockAction(ClockOperation::kAcquire);
189 }
DoDisable()190 pw::Status DoDisable() final {
191 return ValidateClockAction(ClockOperation::kRelease);
192 }
193
194 uint32_t selector_;
195 uint32_t selector_enable_;
196 uint32_t selector_disable_;
197 struct clock_selector_test_data& test_data_;
198 friend class ClockTreeSetSource;
199 };
200
201 using ClockSelectorTestBlocking = ClockSelectorTest<ElementBlocking>;
202 using ClockSelectorTestNonBlockingMightFail =
203 ClockSelectorTest<ElementNonBlockingMightFail>;
204
205 class ClockTreeSetSource : public ClockTree {
206 public:
SetSource(ClockSelectorTestBlocking & element,ElementBlocking & new_source,uint32_t selector_enable,uint32_t selector_disable,bool permit_change_if_in_use)207 pw::Status SetSource(ClockSelectorTestBlocking& element,
208 ElementBlocking& new_source,
209 uint32_t selector_enable,
210 uint32_t selector_disable,
211 bool permit_change_if_in_use) {
212 std::lock_guard lock(mutex_);
213 return element.SetSource(
214 new_source, selector_enable, selector_disable, permit_change_if_in_use);
215 }
216
SetSource(ClockSelectorTestNonBlockingMightFail & element,ElementNonBlockingMightFail & new_source,uint32_t selector_enable,uint32_t selector_disable,bool permit_change_if_in_use)217 pw::Status SetSource(ClockSelectorTestNonBlockingMightFail& element,
218 ElementNonBlockingMightFail& new_source,
219 uint32_t selector_enable,
220 uint32_t selector_disable,
221 bool permit_change_if_in_use) {
222 std::lock_guard lock(interrupt_spin_lock_);
223 return element.SetSource(
224 new_source, selector_enable, selector_disable, permit_change_if_in_use);
225 }
226 };
227
228 struct clock_source_state_test_call_data {
229 uint32_t value;
230 ClockOperation op;
231 };
232
233 struct clock_source_state_test_data {
234 uint32_t num_expected_calls;
235 uint32_t num_calls;
236 struct clock_source_state_test_call_data* data;
237 };
238
239 template <typename ElementType>
240 class ClockSourceStateTest : public ClockSource<ElementType> {
241 public:
ClockSourceStateTest(uint32_t value,uint32_t * clock_state,struct clock_source_state_test_data & test_data)242 constexpr ClockSourceStateTest(uint32_t value,
243 uint32_t* clock_state,
244 struct clock_source_state_test_data& test_data)
245 : value_(value), clock_state_(clock_state), test_data_(test_data) {}
246
247 private:
ValidateClockAction(ClockOperation op)248 void ValidateClockAction(ClockOperation op) {
249 if (test_data_.num_calls < test_data_.num_expected_calls) {
250 uint32_t i = test_data_.num_calls;
251 EXPECT_EQ(test_data_.data[i].value, value_);
252 EXPECT_EQ(test_data_.data[i].op, op);
253 }
254 test_data_.num_calls++;
255 }
256
DoEnable()257 pw::Status DoEnable() final {
258 *clock_state_ |= value_;
259 ValidateClockAction(ClockOperation::kAcquire);
260 return pw::OkStatus();
261 }
262
DoDisable()263 pw::Status DoDisable() final {
264 *clock_state_ &= ~value_;
265 ValidateClockAction(ClockOperation::kRelease);
266 return pw::OkStatus();
267 }
268
269 uint32_t value_;
270 uint32_t* clock_state_;
271 struct clock_source_state_test_data& test_data_;
272 };
273 using ClockSourceStateTestBlocking = ClockSelectorTest<ElementBlocking>;
274 using ClockSourceStateTestNonBlocking =
275 ClockSelectorTest<ElementNonBlockingMightFail>;
276
277 template <typename ElementType>
278 class ClockSourceTest : public ClockSource<ElementType> {
279 private:
DoEnable()280 pw::Status DoEnable() final { return pw::OkStatus(); }
281
DoDisable()282 pw::Status DoDisable() final { return pw::OkStatus(); }
283 };
284 using ClockSourceTestBlocking = ClockSourceTest<ElementBlocking>;
285 using ClockSourceTestNonBlocking = ClockSourceTest<ElementNonBlockingMightFail>;
286
287 struct clock_source_failure_test_call_data {
288 ClockOperation op;
289 pw::Status status;
290 };
291
292 struct clock_source_failure_test_data {
293 uint32_t num_expected_calls;
294 uint32_t num_calls;
295 struct clock_source_failure_test_call_data* data;
296 };
297
298 template <typename ElementType>
299 class ClockSourceFailureTest : public ClockSource<ElementType> {
300 public:
ClockSourceFailureTest(struct clock_source_failure_test_data & test_data)301 constexpr ClockSourceFailureTest(
302 struct clock_source_failure_test_data& test_data)
303 : test_data_(test_data) {}
304
305 private:
ValidateClockAction(ClockOperation op)306 pw::Status ValidateClockAction(ClockOperation op) {
307 pw::Status status = pw::Status::OutOfRange();
308 if (test_data_.num_calls < test_data_.num_expected_calls) {
309 uint32_t i = test_data_.num_calls;
310 EXPECT_EQ(test_data_.data[i].op, op);
311 status = test_data_.data[i].status;
312 }
313 test_data_.num_calls++;
314 return status;
315 }
316
DoEnable()317 pw::Status DoEnable() final {
318 return ValidateClockAction(ClockOperation::kAcquire);
319 }
DoDisable()320 pw::Status DoDisable() final {
321 return ValidateClockAction(ClockOperation::kRelease);
322 }
323 struct clock_source_failure_test_data& test_data_;
324 };
325
326 using ClockSourceFailureTestBlocking = ClockSourceFailureTest<ElementBlocking>;
327 using ClockSourceFailureTestNonBlocking =
328 ClockSourceFailureTest<ElementNonBlockingMightFail>;
329
330 template <typename ElementType>
TestClock()331 static void TestClock() {
332 ClockTree clock_tree;
333 pw::Status status;
334 ClockSourceTest<ElementType> clock_a;
335
336 EXPECT_EQ(clock_a.ref_count(), 0u);
337
338 status = clock_tree.Acquire(clock_a);
339 EXPECT_EQ(status.code(), PW_STATUS_OK);
340 EXPECT_EQ(clock_a.ref_count(), 1u);
341
342 status = clock_tree.Acquire(clock_a);
343 EXPECT_EQ(status.code(), PW_STATUS_OK);
344 EXPECT_EQ(clock_a.ref_count(), 2u);
345
346 status = clock_tree.Release(clock_a);
347 EXPECT_EQ(status.code(), PW_STATUS_OK);
348 EXPECT_EQ(clock_a.ref_count(), 1u);
349
350 status = clock_tree.Release(clock_a);
351 EXPECT_EQ(status.code(), PW_STATUS_OK);
352 EXPECT_EQ(clock_a.ref_count(), 0u);
353 }
354
TEST(ClockTree,ClockBlocking)355 TEST(ClockTree, ClockBlocking) { TestClock<ElementBlocking>(); }
356
TEST(ClockTree,ClockNonBlocking)357 TEST(ClockTree, ClockNonBlocking) { TestClock<ElementNonBlockingMightFail>(); }
358
359 // Validate that the correct divider values are getting set.
360 // The `clock_divider_b` doesn't override the `DoDisable` function,
361 // so only the ClockDividerNoDoDisableTest's `DoEnable` method will be called.
362 template <typename ElementType>
TestClockDivider()363 static void TestClockDivider() {
364 const uint32_t kClockDividerB = 23;
365 const uint32_t kClockDividerC = 42;
366
367 struct clock_divider_test_call_data call_data[] = {
368 {kClockDividerB, 2, ClockOperation::kAcquire, pw::OkStatus()},
369 {kClockDividerC, 4, ClockOperation::kAcquire, pw::OkStatus()},
370 {kClockDividerC, 4, ClockOperation::kRelease, pw::OkStatus()}};
371
372 struct clock_divider_test_data test_data;
373 INIT_TEST_DATA(test_data, call_data);
374 ClockTree clock_tree;
375
376 ClockSourceTest<ElementType> clock_a;
377 ClockDividerNoDoDisableTest<ElementType> clock_divider_b(
378 clock_a, kClockDividerB, 2, test_data);
379 ClockDividerTest<ElementType> clock_divider_c(
380 clock_a, kClockDividerC, 4, test_data);
381 ClockDivider& clock_divider_b_abstract = clock_divider_b;
382 Element& clock_divider_b_element = clock_divider_b_abstract.element();
383 pw::Status status;
384
385 EXPECT_EQ(clock_a.ref_count(), 0u);
386 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
387 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
388
389 status = clock_tree.Acquire(clock_divider_b);
390 EXPECT_EQ(status.code(), PW_STATUS_OK);
391 EXPECT_EQ(clock_a.ref_count(), 1u);
392 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
393 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
394
395 status = clock_tree.Acquire(clock_divider_b_element);
396 EXPECT_EQ(status.code(), PW_STATUS_OK);
397 EXPECT_EQ(clock_a.ref_count(), 1u);
398 EXPECT_EQ(clock_divider_b.ref_count(), 2u);
399 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
400
401 status = clock_tree.Acquire(clock_divider_c);
402 EXPECT_EQ(status.code(), PW_STATUS_OK);
403 EXPECT_EQ(clock_a.ref_count(), 2u);
404 EXPECT_EQ(clock_divider_b.ref_count(), 2u);
405 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
406
407 status = clock_tree.Release(clock_divider_b);
408 EXPECT_EQ(status.code(), PW_STATUS_OK);
409 EXPECT_EQ(clock_a.ref_count(), 2u);
410 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
411 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
412
413 // Releasing `clock_divider_b` won't be tracked, since
414 // only the base class `DoDisable` method will be called.
415 status = clock_tree.Release(clock_divider_b_element);
416 EXPECT_EQ(status.code(), PW_STATUS_OK);
417 EXPECT_EQ(clock_a.ref_count(), 1u);
418 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
419 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
420
421 status = clock_tree.Release(clock_divider_c);
422 EXPECT_EQ(status.code(), PW_STATUS_OK);
423 EXPECT_EQ(clock_a.ref_count(), 0u);
424 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
425 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
426
427 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
428 }
429
TEST(ClockTree,DividerBlocking)430 TEST(ClockTree, DividerBlocking) { TestClockDivider<ElementBlocking>(); }
431
TEST(ClockTree,DividerNonBlocking)432 TEST(ClockTree, DividerNonBlocking) {
433 TestClockDivider<ElementNonBlockingMightFail>();
434 }
435
436 // Validate that different divider values can be set.
437 template <typename ElementType>
TestClockDividerSet()438 static void TestClockDividerSet() {
439 const uint32_t kClockDivider = 23;
440
441 struct clock_divider_test_call_data call_data[] = {
442 {kClockDivider, 2, ClockOperation::kAcquire, pw::OkStatus()},
443 {kClockDivider, 4, ClockOperation::kAcquire, pw::OkStatus()},
444 {kClockDivider, 4, ClockOperation::kRelease, pw::OkStatus()},
445 {kClockDivider, 6, ClockOperation::kAcquire, pw::OkStatus()},
446 {kClockDivider, 6, ClockOperation::kRelease, pw::OkStatus()}};
447
448 struct clock_divider_test_data test_data;
449 INIT_TEST_DATA(test_data, call_data);
450 ClockTree clock_tree;
451 pw::Status status;
452
453 ClockSourceTest<ElementType> clock_a;
454 ClockDividerTest<ElementType> clock_divider_b(
455 clock_a, kClockDivider, 2, test_data);
456 ClockDivider& clock_divider_b_abstract = clock_divider_b;
457
458 EXPECT_EQ(clock_a.ref_count(), 0u);
459 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
460
461 status = clock_tree.Acquire(clock_divider_b);
462 EXPECT_EQ(status.code(), PW_STATUS_OK);
463 EXPECT_EQ(clock_a.ref_count(), 1u);
464 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
465
466 status = clock_tree.SetDividerValue(clock_divider_b_abstract, 4);
467 EXPECT_EQ(status.code(), PW_STATUS_OK);
468 EXPECT_EQ(clock_a.ref_count(), 1u);
469 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
470
471 status = clock_tree.Release(clock_divider_b);
472 EXPECT_EQ(status.code(), PW_STATUS_OK);
473 EXPECT_EQ(clock_a.ref_count(), 0u);
474 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
475
476 status = clock_tree.SetDividerValue(clock_divider_b, 6);
477 EXPECT_EQ(status.code(), PW_STATUS_OK);
478 EXPECT_EQ(clock_a.ref_count(), 0u);
479 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
480
481 status = clock_tree.Acquire(clock_divider_b);
482 EXPECT_EQ(status.code(), PW_STATUS_OK);
483 EXPECT_EQ(clock_a.ref_count(), 1u);
484 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
485
486 status = clock_tree.Release(clock_divider_b);
487 EXPECT_EQ(status.code(), PW_STATUS_OK);
488 EXPECT_EQ(clock_a.ref_count(), 0u);
489 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
490
491 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
492 }
493
TEST(ClockTree,ClockDividerSetBlocking)494 TEST(ClockTree, ClockDividerSetBlocking) {
495 TestClockDividerSet<ElementBlocking>();
496 }
497
TEST(ClockTree,ClockDividerSetNonBlocking)498 TEST(ClockTree, ClockDividerSetNonBlocking) {
499 TestClockDividerSet<ElementNonBlockingMightFail>();
500 }
501
502 // Validate that if the `DoEnable` function fails that gets called as part
503 // of a divider update, that the state of the divider doesn't change.
504 template <typename ElementType>
TestClockDividerSetFailure()505 static void TestClockDividerSetFailure() {
506 const uint32_t kClockDivider = 23;
507
508 struct clock_divider_test_call_data call_data[] = {
509 {kClockDivider, 2, ClockOperation::kAcquire, pw::OkStatus()},
510 {kClockDivider, 4, ClockOperation::kAcquire, pw::Status::Internal()},
511 {kClockDivider, 2, ClockOperation::kRelease, pw::OkStatus()}};
512
513 struct clock_divider_test_data test_data;
514 INIT_TEST_DATA(test_data, call_data);
515 ClockTree clock_tree;
516 pw::Status status;
517
518 ClockSourceTest<ElementType> clock_a;
519 ClockDividerTest<ElementType> clock_divider_b(
520 clock_a, kClockDivider, 2, test_data);
521
522 EXPECT_EQ(clock_a.ref_count(), 0u);
523 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
524
525 status = clock_tree.Acquire(clock_divider_b);
526 EXPECT_EQ(status.code(), PW_STATUS_OK);
527 EXPECT_EQ(clock_a.ref_count(), 1u);
528 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
529
530 status = clock_tree.SetDividerValue(clock_divider_b, 4);
531 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
532 EXPECT_EQ(clock_a.ref_count(), 1u);
533 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
534
535 status = clock_tree.Release(clock_divider_b);
536 EXPECT_EQ(status.code(), PW_STATUS_OK);
537 EXPECT_EQ(clock_a.ref_count(), 0u);
538 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
539
540 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
541 }
542
TEST(ClockTree,ClockDividerSetFailureBlocking)543 TEST(ClockTree, ClockDividerSetFailureBlocking) {
544 TestClockDividerSetFailure<ElementBlocking>();
545 }
546
TEST(ClockTree,ClockDividerSetFailureNonBlocking)547 TEST(ClockTree, ClockDividerSetFailureNonBlocking) {
548 TestClockDividerSetFailure<ElementNonBlockingMightFail>();
549 }
550
551 // Validate that a selector enables and disables correctly.
552 template <typename ElementType>
TestClockSelector()553 static void TestClockSelector() {
554 const uint32_t kSelector = 41;
555 struct clock_selector_test_call_data call_data[] = {
556 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
557 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()},
558 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
559 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()}};
560
561 struct clock_selector_test_data test_data;
562 INIT_TEST_DATA(test_data, call_data);
563 ClockTree clock_tree;
564 pw::Status status;
565
566 ClockSourceTest<ElementType> clock_a;
567 ClockSelectorTest<ElementType> clock_selector_b(
568 clock_a, kSelector, 2, 7, test_data);
569 Element& clock_selector_b_element = clock_selector_b;
570
571 EXPECT_EQ(clock_a.ref_count(), 0u);
572 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
573
574 status = clock_tree.Acquire(clock_selector_b);
575 EXPECT_EQ(status.code(), PW_STATUS_OK);
576 EXPECT_EQ(clock_a.ref_count(), 1u);
577 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
578
579 status = clock_tree.Acquire(clock_selector_b_element);
580 EXPECT_EQ(status.code(), PW_STATUS_OK);
581 EXPECT_EQ(clock_a.ref_count(), 1u);
582 EXPECT_EQ(clock_selector_b.ref_count(), 2u);
583
584 status = clock_tree.Release(clock_selector_b);
585 EXPECT_EQ(status.code(), PW_STATUS_OK);
586 EXPECT_EQ(clock_a.ref_count(), 1u);
587 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
588
589 status = clock_tree.Release(clock_selector_b_element);
590 EXPECT_EQ(status.code(), PW_STATUS_OK);
591 EXPECT_EQ(clock_a.ref_count(), 0u);
592 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
593
594 status = clock_tree.Acquire(clock_selector_b);
595 EXPECT_EQ(status.code(), PW_STATUS_OK);
596 EXPECT_EQ(clock_a.ref_count(), 1u);
597 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
598
599 status = clock_tree.Release(clock_selector_b);
600 EXPECT_EQ(status.code(), PW_STATUS_OK);
601 EXPECT_EQ(clock_a.ref_count(), 0u);
602 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
603
604 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
605 }
606
TEST(ClockTree,ClockSelectorBlocking)607 TEST(ClockTree, ClockSelectorBlocking) { TestClockSelector<ElementBlocking>(); }
608
TEST(ClockTree,ClockSelectorNonBlocking)609 TEST(ClockTree, ClockSelectorNonBlocking) {
610 TestClockSelector<ElementNonBlockingMightFail>();
611 }
612
613 // Validate that we can update the source of a selector.
614 template <typename ElementType>
TestClockSelectorUpdateSource()615 static void TestClockSelectorUpdateSource() {
616 const bool kPermitUpdateWhileInUse = true;
617 const bool kProhibitUpdateWhileInUse = false;
618 const uint32_t kSelector = 41;
619 struct clock_selector_test_call_data call_data[] = {
620 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
621 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
622 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
623 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()},
624 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
625 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()},
626 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
627 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
628 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
629 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()}};
630
631 struct clock_selector_test_data test_data;
632 INIT_TEST_DATA(test_data, call_data);
633 ClockTreeSetSource clock_tree;
634 pw::Status status;
635
636 ClockSourceTest<ElementType> clock_a;
637 ClockSourceTest<ElementType> clock_b;
638 ClockSelectorTest<ElementType> clock_selector_c(
639 clock_a, kSelector, 1, 8, test_data);
640
641 EXPECT_EQ(clock_a.ref_count(), 0u);
642 EXPECT_EQ(clock_b.ref_count(), 0u);
643 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
644
645 status = clock_tree.Acquire(clock_selector_c);
646 EXPECT_EQ(status.code(), PW_STATUS_OK);
647 EXPECT_EQ(clock_a.ref_count(), 1u);
648 EXPECT_EQ(clock_b.ref_count(), 0u);
649 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
650
651 // Validate that we cannot change the source when the reference count is held,
652 // while we are prohibited from changing the source with an active reference
653 // count.
654 status = clock_tree.SetSource(
655 clock_selector_c, clock_b, 20, 40, kProhibitUpdateWhileInUse);
656 EXPECT_EQ(status.code(), PW_STATUS_FAILED_PRECONDITION);
657 EXPECT_EQ(clock_a.ref_count(), 1u);
658 EXPECT_EQ(clock_b.ref_count(), 0u);
659 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
660
661 // Validate that we can change the source when the reference count is held,
662 // while we are permitted to change the source with an active reference count.
663 status = clock_tree.SetSource(
664 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
665 EXPECT_EQ(status.code(), PW_STATUS_OK);
666 EXPECT_EQ(clock_a.ref_count(), 0u);
667 EXPECT_EQ(clock_b.ref_count(), 1u);
668 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
669
670 status = clock_tree.Acquire(clock_selector_c);
671 EXPECT_EQ(status.code(), PW_STATUS_OK);
672 EXPECT_EQ(clock_a.ref_count(), 0u);
673 EXPECT_EQ(clock_b.ref_count(), 1u);
674 EXPECT_EQ(clock_selector_c.ref_count(), 2u);
675
676 status = clock_tree.Release(clock_selector_c);
677 EXPECT_EQ(status.code(), PW_STATUS_OK);
678 EXPECT_EQ(clock_a.ref_count(), 0u);
679 EXPECT_EQ(clock_b.ref_count(), 1u);
680 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
681
682 status = clock_tree.Release(clock_selector_c);
683 EXPECT_EQ(status.code(), PW_STATUS_OK);
684 EXPECT_EQ(clock_a.ref_count(), 0u);
685 EXPECT_EQ(clock_b.ref_count(), 0u);
686 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
687
688 // Validate that we are re-enabling clock_b.
689 status = clock_tree.Acquire(clock_selector_c);
690 EXPECT_EQ(status.code(), PW_STATUS_OK);
691 EXPECT_EQ(clock_a.ref_count(), 0u);
692 EXPECT_EQ(clock_b.ref_count(), 1u);
693 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
694
695 status = clock_tree.Release(clock_selector_c);
696 EXPECT_EQ(status.code(), PW_STATUS_OK);
697 EXPECT_EQ(clock_a.ref_count(), 0u);
698 EXPECT_EQ(clock_b.ref_count(), 0u);
699 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
700
701 // Validate that we can change the source when no reference count is held,
702 // while we are prohibited from changing the source with an active reference
703 // count.
704 status = clock_tree.SetSource(
705 clock_selector_c, clock_a, 1, 8, kProhibitUpdateWhileInUse);
706 EXPECT_EQ(status.code(), PW_STATUS_OK);
707 EXPECT_EQ(clock_a.ref_count(), 0u);
708 EXPECT_EQ(clock_b.ref_count(), 0u);
709 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
710
711 // Validate that we are enabling clock_a.
712 status = clock_tree.Acquire(clock_selector_c);
713 EXPECT_EQ(status.code(), PW_STATUS_OK);
714 EXPECT_EQ(clock_a.ref_count(), 1u);
715 EXPECT_EQ(clock_b.ref_count(), 0u);
716 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
717
718 status = clock_tree.Release(clock_selector_c);
719 EXPECT_EQ(status.code(), PW_STATUS_OK);
720 EXPECT_EQ(clock_a.ref_count(), 0u);
721 EXPECT_EQ(clock_b.ref_count(), 0u);
722 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
723
724 // Validate that we can change the source when no reference count is held,
725 // while we are permitted to change the source with an active reference count.
726 status = clock_tree.SetSource(
727 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
728 EXPECT_EQ(status.code(), PW_STATUS_OK);
729 EXPECT_EQ(clock_a.ref_count(), 0u);
730 EXPECT_EQ(clock_b.ref_count(), 0u);
731 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
732
733 // Validate that we are enabling clock_b.
734 status = clock_tree.Acquire(clock_selector_c);
735 EXPECT_EQ(status.code(), PW_STATUS_OK);
736 EXPECT_EQ(clock_a.ref_count(), 0u);
737 EXPECT_EQ(clock_b.ref_count(), 1u);
738 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
739
740 status = clock_tree.Release(clock_selector_c);
741 EXPECT_EQ(status.code(), PW_STATUS_OK);
742 EXPECT_EQ(clock_a.ref_count(), 0u);
743 EXPECT_EQ(clock_b.ref_count(), 0u);
744 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
745 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
746 }
747
TEST(ClockTree,ClockSelectorUpdateSourceBlocking)748 TEST(ClockTree, ClockSelectorUpdateSourceBlocking) {
749 TestClockSelectorUpdateSource<ElementBlocking>();
750 }
751
TEST(ClockTree,ClockSelectorUpdateSourceNonBlocking)752 TEST(ClockTree, ClockSelectorUpdateSourceNonBlocking) {
753 TestClockSelectorUpdateSource<ElementNonBlockingMightFail>();
754 }
755
756 // Validate that `ClockSource` and current configured selector remain
757 // unchanged if updating clock source fails when acquiring reference
758 // to new source.
759 template <typename ElementType>
TestClockSelectorUpdateSourceFailure1()760 static void TestClockSelectorUpdateSourceFailure1() {
761 const bool kPermitUpdateWhileInUse = true;
762
763 struct clock_source_failure_test_call_data clock_a_call_data[] = {
764 {ClockOperation::kAcquire, pw::OkStatus()},
765 {ClockOperation::kRelease, pw::OkStatus()},
766 {ClockOperation::kAcquire, pw::OkStatus()},
767 {ClockOperation::kRelease, pw::OkStatus()}};
768
769 struct clock_source_failure_test_data clock_a_test_data;
770 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
771 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
772 ;
773
774 struct clock_source_failure_test_call_data clock_b_call_data[] = {
775 {ClockOperation::kAcquire, pw::Status::Internal()}};
776
777 struct clock_source_failure_test_data clock_b_test_data;
778 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
779 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
780 ;
781
782 const uint32_t kSelector = 41;
783 struct clock_selector_test_call_data selector_call_data[] = {
784 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
785 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
786 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
787 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
788
789 struct clock_selector_test_data selector_c_test_data;
790 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
791
792 ClockTreeSetSource clock_tree;
793 pw::Status status;
794
795 ClockSelectorTest<ElementType> clock_selector_c(
796 clock_a, kSelector, 1, 8, selector_c_test_data);
797
798 EXPECT_EQ(clock_a.ref_count(), 0u);
799 EXPECT_EQ(clock_b.ref_count(), 0u);
800 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
801
802 status = clock_tree.Acquire(clock_selector_c);
803 EXPECT_EQ(status.code(), PW_STATUS_OK);
804 EXPECT_EQ(clock_a.ref_count(), 1u);
805 EXPECT_EQ(clock_b.ref_count(), 0u);
806 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
807
808 // Try to acquire a reference to the new source, which will fail. Then
809 // validate that everything remained in place, and that the selector
810 // configuration hasn't changed by releasing and reacquiring the
811 // `clock_selector_c`.
812 status = clock_tree.SetSource(
813 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
814 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
815 EXPECT_EQ(clock_a.ref_count(), 1u);
816 EXPECT_EQ(clock_b.ref_count(), 0u);
817 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
818
819 // Release the selector and verify that the correct selector value gets
820 // configured.
821 status = clock_tree.Release(clock_selector_c);
822 EXPECT_EQ(status.code(), PW_STATUS_OK);
823 EXPECT_EQ(clock_a.ref_count(), 0u);
824 EXPECT_EQ(clock_b.ref_count(), 0u);
825 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
826
827 // Acquire and release the selector and verify that the correct selector
828 // values get configured again.
829 status = clock_tree.Acquire(clock_selector_c);
830 EXPECT_EQ(status.code(), PW_STATUS_OK);
831 EXPECT_EQ(clock_a.ref_count(), 1u);
832 EXPECT_EQ(clock_b.ref_count(), 0u);
833 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
834
835 status = clock_tree.Release(clock_selector_c);
836 EXPECT_EQ(status.code(), PW_STATUS_OK);
837 EXPECT_EQ(clock_a.ref_count(), 0u);
838 EXPECT_EQ(clock_b.ref_count(), 0u);
839 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
840
841 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
842 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
843 EXPECT_EQ(selector_c_test_data.num_calls,
844 selector_c_test_data.num_expected_calls);
845 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure1Blocking)846 TEST(ClockTree, ClockSelectorUpdateSourceFailure1Blocking) {
847 TestClockSelectorUpdateSourceFailure1<ElementBlocking>();
848 }
849
TEST(ClockTree,ClockSelectorUpdateSourceFailure1NonBlocking)850 TEST(ClockTree, ClockSelectorUpdateSourceFailure1NonBlocking) {
851 TestClockSelectorUpdateSourceFailure1<ElementNonBlockingMightFail>();
852 }
853
854 // Validate that `ClockSource` and current configured selector remain
855 // unchanged if `DoDisable` call fails of current selector. The
856 // new source reference count should remain unchanged at the end.
857 template <typename ElementType>
TestClockSelectorUpdateSourceFailure2()858 static void TestClockSelectorUpdateSourceFailure2() {
859 const bool kPermitUpdateWhileInUse = true;
860
861 struct clock_source_failure_test_call_data clock_a_call_data[] = {
862 {ClockOperation::kAcquire, pw::OkStatus()},
863 {ClockOperation::kRelease, pw::OkStatus()},
864 {ClockOperation::kAcquire, pw::OkStatus()},
865 {ClockOperation::kRelease, pw::OkStatus()}};
866
867 struct clock_source_failure_test_data clock_a_test_data;
868 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
869 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
870 ;
871
872 struct clock_source_failure_test_call_data clock_b_call_data[] = {
873 {ClockOperation::kAcquire, pw::OkStatus()},
874 {ClockOperation::kRelease, pw::OkStatus()}};
875
876 struct clock_source_failure_test_data clock_b_test_data;
877 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
878 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
879 ;
880
881 const uint32_t kSelector = 41;
882 struct clock_selector_test_call_data selector_call_data[] = {
883 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
884 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()},
885 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
886 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
887 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
888
889 struct clock_selector_test_data selector_c_test_data;
890 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
891
892 ClockTreeSetSource clock_tree;
893 pw::Status status;
894
895 ClockSelectorTest<ElementType> clock_selector_c(
896 clock_a, kSelector, 1, 8, selector_c_test_data);
897
898 EXPECT_EQ(clock_a.ref_count(), 0u);
899 EXPECT_EQ(clock_b.ref_count(), 0u);
900 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
901
902 status = clock_tree.Acquire(clock_selector_c);
903 EXPECT_EQ(status.code(), PW_STATUS_OK);
904 EXPECT_EQ(clock_a.ref_count(), 1u);
905 EXPECT_EQ(clock_b.ref_count(), 0u);
906 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
907
908 // Try to disable the old source, which will fail. Then validate that
909 // everything remained in place, and that the selector configuration hasn't
910 // changed by releasing and reacquiring the `clock_selector_c`.
911 status = clock_tree.SetSource(
912 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
913 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
914 EXPECT_EQ(clock_a.ref_count(), 1u);
915 EXPECT_EQ(clock_b.ref_count(), 0u);
916 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
917
918 // Release the selector and verify that the correct selector value gets
919 // configured.
920 status = clock_tree.Release(clock_selector_c);
921 EXPECT_EQ(status.code(), PW_STATUS_OK);
922 EXPECT_EQ(clock_a.ref_count(), 0u);
923 EXPECT_EQ(clock_b.ref_count(), 0u);
924 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
925
926 // Acquire and release the selector and verify that the correct selector
927 // values get configured again.
928 status = clock_tree.Acquire(clock_selector_c);
929 EXPECT_EQ(status.code(), PW_STATUS_OK);
930 EXPECT_EQ(clock_a.ref_count(), 1u);
931 EXPECT_EQ(clock_b.ref_count(), 0u);
932 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
933
934 status = clock_tree.Release(clock_selector_c);
935 EXPECT_EQ(status.code(), PW_STATUS_OK);
936 EXPECT_EQ(clock_a.ref_count(), 0u);
937 EXPECT_EQ(clock_b.ref_count(), 0u);
938 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
939
940 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
941 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
942 EXPECT_EQ(selector_c_test_data.num_calls,
943 selector_c_test_data.num_expected_calls);
944 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure2Blocking)945 TEST(ClockTree, ClockSelectorUpdateSourceFailure2Blocking) {
946 TestClockSelectorUpdateSourceFailure2<ElementBlocking>();
947 }
948
TEST(ClockTree,ClockSelectorUpdateSourceFailure2NonBlocking)949 TEST(ClockTree, ClockSelectorUpdateSourceFailure2NonBlocking) {
950 TestClockSelectorUpdateSourceFailure2<ElementNonBlockingMightFail>();
951 }
952
953 // Validate that `ClockSource` and current configured selector remain
954 // unchanged if `DoDisable` call fails of current selector.
955 // The `DoDisable` call of the new source will fail as well, so validate
956 // that the new source got enabled as well.
957 template <typename ElementType>
TestClockSelectorUpdateSourceFailure3()958 static void TestClockSelectorUpdateSourceFailure3() {
959 const bool kPermitUpdateWhileInUse = true;
960
961 struct clock_source_failure_test_call_data clock_a_call_data[] = {
962 {ClockOperation::kAcquire, pw::OkStatus()},
963 {ClockOperation::kRelease, pw::OkStatus()},
964 {ClockOperation::kAcquire, pw::OkStatus()},
965 {ClockOperation::kRelease, pw::OkStatus()}};
966
967 struct clock_source_failure_test_data clock_a_test_data;
968 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
969 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
970 ;
971
972 struct clock_source_failure_test_call_data clock_b_call_data[] = {
973 {ClockOperation::kAcquire, pw::OkStatus()},
974 {ClockOperation::kRelease, pw::Status::FailedPrecondition()}};
975
976 struct clock_source_failure_test_data clock_b_test_data;
977 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
978 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
979 ;
980
981 const uint32_t kSelector = 41;
982 struct clock_selector_test_call_data selector_call_data[] = {
983 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
984 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()},
985 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
986 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
987 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
988
989 struct clock_selector_test_data selector_c_test_data;
990 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
991
992 ClockTreeSetSource clock_tree;
993 pw::Status status;
994
995 ClockSelectorTest<ElementType> clock_selector_c(
996 clock_a, kSelector, 1, 8, selector_c_test_data);
997
998 EXPECT_EQ(clock_a.ref_count(), 0u);
999 EXPECT_EQ(clock_b.ref_count(), 0u);
1000 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1001
1002 status = clock_tree.Acquire(clock_selector_c);
1003 EXPECT_EQ(status.code(), PW_STATUS_OK);
1004 EXPECT_EQ(clock_a.ref_count(), 1u);
1005 EXPECT_EQ(clock_b.ref_count(), 0u);
1006 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1007
1008 // Try to disable the old source, which will fail, and try to disable the new
1009 // source which will fail as well. Then validate that everything remained in
1010 // place, and that the selector configuration hasn't changed by releasing and
1011 // reacquiring the `clock_selector_c`, but also that the new source got
1012 // acquired.
1013 status = clock_tree.SetSource(
1014 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1015 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1016 EXPECT_EQ(clock_a.ref_count(), 1u);
1017 EXPECT_EQ(clock_b.ref_count(), 1u);
1018 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1019
1020 // Release the selector and verify that the correct selector value gets
1021 // configured.
1022 status = clock_tree.Release(clock_selector_c);
1023 EXPECT_EQ(status.code(), PW_STATUS_OK);
1024 EXPECT_EQ(clock_a.ref_count(), 0u);
1025 EXPECT_EQ(clock_b.ref_count(), 1u);
1026 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1027
1028 // Acquire and release the selector and verify that the correct selector
1029 // values get configured again.
1030 status = clock_tree.Acquire(clock_selector_c);
1031 EXPECT_EQ(status.code(), PW_STATUS_OK);
1032 EXPECT_EQ(clock_a.ref_count(), 1u);
1033 EXPECT_EQ(clock_b.ref_count(), 1u);
1034 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1035
1036 status = clock_tree.Release(clock_selector_c);
1037 EXPECT_EQ(status.code(), PW_STATUS_OK);
1038 EXPECT_EQ(clock_a.ref_count(), 0u);
1039 EXPECT_EQ(clock_b.ref_count(), 1u);
1040 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1041
1042 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1043 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1044 EXPECT_EQ(selector_c_test_data.num_calls,
1045 selector_c_test_data.num_expected_calls);
1046 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure3Blocking)1047 TEST(ClockTree, ClockSelectorUpdateSourceFailure3Blocking) {
1048 TestClockSelectorUpdateSourceFailure3<ElementBlocking>();
1049 }
1050
TEST(ClockTree,ClockSelectorUpdateSourceFailure3NonBlocking)1051 TEST(ClockTree, ClockSelectorUpdateSourceFailure3NonBlocking) {
1052 TestClockSelectorUpdateSourceFailure3<ElementNonBlockingMightFail>();
1053 }
1054
1055 // Validate that `ClockSource` gets disabled, if new clock source's `DoEnable`
1056 // call fails.
1057 template <typename ElementType>
TestClockSelectorUpdateSourceFailure4()1058 static void TestClockSelectorUpdateSourceFailure4() {
1059 const bool kPermitUpdateWhileInUse = true;
1060
1061 struct clock_source_failure_test_call_data clock_a_call_data[] = {
1062 {ClockOperation::kAcquire, pw::OkStatus()},
1063 {ClockOperation::kRelease, pw::OkStatus()},
1064 {ClockOperation::kAcquire, pw::OkStatus()},
1065 {ClockOperation::kRelease, pw::OkStatus()}};
1066
1067 struct clock_source_failure_test_data clock_a_test_data;
1068 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
1069 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
1070 ;
1071
1072 struct clock_source_failure_test_call_data clock_b_call_data[] = {
1073 {ClockOperation::kAcquire, pw::OkStatus()},
1074 {ClockOperation::kRelease, pw::OkStatus()}};
1075
1076 struct clock_source_failure_test_data clock_b_test_data;
1077 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
1078 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
1079 ;
1080
1081 const uint32_t kSelector = 41;
1082 struct clock_selector_test_call_data selector_call_data[] = {
1083 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1084 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
1085 {kSelector, 2, ClockOperation::kAcquire, pw::Status::Internal()},
1086 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1087 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1088
1089 struct clock_selector_test_data selector_c_test_data;
1090 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
1091
1092 ClockTreeSetSource clock_tree;
1093 pw::Status status;
1094
1095 ClockSelectorTest<ElementType> clock_selector_c(
1096 clock_a, kSelector, 1, 8, selector_c_test_data);
1097
1098 EXPECT_EQ(clock_a.ref_count(), 0u);
1099 EXPECT_EQ(clock_b.ref_count(), 0u);
1100 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1101
1102 status = clock_tree.Acquire(clock_selector_c);
1103 EXPECT_EQ(status.code(), PW_STATUS_OK);
1104 EXPECT_EQ(clock_a.ref_count(), 1u);
1105 EXPECT_EQ(clock_b.ref_count(), 0u);
1106 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1107
1108 // Try to enable the new source, which will fail. Since the new source failed
1109 // to enable after we disabled the old source, everything should be disabled
1110 // at this point. When we enable the selector again, the old source should get
1111 // re-enabled again.
1112 status = clock_tree.SetSource(
1113 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1114 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1115 EXPECT_EQ(clock_a.ref_count(), 0u);
1116 EXPECT_EQ(clock_b.ref_count(), 0u);
1117 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1118
1119 // Acquire and release the selector and verify that the correct selector
1120 // values get configured again.
1121 status = clock_tree.Acquire(clock_selector_c);
1122 EXPECT_EQ(status.code(), PW_STATUS_OK);
1123 EXPECT_EQ(clock_a.ref_count(), 1u);
1124 EXPECT_EQ(clock_b.ref_count(), 0u);
1125 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1126
1127 status = clock_tree.Release(clock_selector_c);
1128 EXPECT_EQ(status.code(), PW_STATUS_OK);
1129 EXPECT_EQ(clock_a.ref_count(), 0u);
1130 EXPECT_EQ(clock_b.ref_count(), 0u);
1131 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1132
1133 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1134 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1135 EXPECT_EQ(selector_c_test_data.num_calls,
1136 selector_c_test_data.num_expected_calls);
1137 }
1138
TEST(ClockTree,ClockSelectorUpdateSourceFailure4Blocking)1139 TEST(ClockTree, ClockSelectorUpdateSourceFailure4Blocking) {
1140 TestClockSelectorUpdateSourceFailure4<ElementBlocking>();
1141 }
1142
TEST(ClockTree,ClockSelectorUpdateSourceFailure4NonBlocking)1143 TEST(ClockTree, ClockSelectorUpdateSourceFailure4NonBlocking) {
1144 TestClockSelectorUpdateSourceFailure4<ElementNonBlockingMightFail>();
1145 }
1146
1147 // Validate that we try to release `ClockSource` if new clock source gets
1148 // enabled, and that the failure of release has no impact on newly conifgured
1149 // selector setting.
1150 template <typename ElementType>
TestClockSelectorUpdateSourceFailure5()1151 static void TestClockSelectorUpdateSourceFailure5() {
1152 const bool kPermitUpdateWhileInUse = true;
1153
1154 struct clock_source_failure_test_call_data clock_a_call_data[] = {
1155 {ClockOperation::kAcquire, pw::OkStatus()},
1156 {ClockOperation::kRelease, pw::Status::Internal()}};
1157
1158 struct clock_source_failure_test_data clock_a_test_data;
1159 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
1160 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
1161 ;
1162
1163 struct clock_source_failure_test_call_data clock_b_call_data[] = {
1164 {ClockOperation::kAcquire, pw::OkStatus()},
1165 {ClockOperation::kRelease, pw::OkStatus()}};
1166
1167 struct clock_source_failure_test_data clock_b_test_data;
1168 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
1169 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
1170 ;
1171
1172 const uint32_t kSelector = 41;
1173 struct clock_selector_test_call_data selector_call_data[] = {
1174 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1175 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
1176 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
1177 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()}};
1178
1179 struct clock_selector_test_data selector_c_test_data;
1180 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
1181
1182 ClockTreeSetSource clock_tree;
1183 pw::Status status;
1184
1185 ClockSelectorTest<ElementType> clock_selector_c(
1186 clock_a, kSelector, 1, 8, selector_c_test_data);
1187
1188 EXPECT_EQ(clock_a.ref_count(), 0u);
1189 EXPECT_EQ(clock_b.ref_count(), 0u);
1190 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1191
1192 status = clock_tree.Acquire(clock_selector_c);
1193 EXPECT_EQ(status.code(), PW_STATUS_OK);
1194 EXPECT_EQ(clock_a.ref_count(), 1u);
1195 EXPECT_EQ(clock_b.ref_count(), 0u);
1196 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1197
1198 // Enable the new source, but releasing the old source fails. The new source
1199 // should be active, but the old source will keep its reference.
1200 status = clock_tree.SetSource(
1201 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1202 EXPECT_EQ(status.code(), PW_STATUS_OK);
1203 EXPECT_EQ(clock_a.ref_count(), 1u);
1204 EXPECT_EQ(clock_b.ref_count(), 1u);
1205 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1206
1207 status = clock_tree.Release(clock_selector_c);
1208 EXPECT_EQ(status.code(), PW_STATUS_OK);
1209 EXPECT_EQ(clock_a.ref_count(), 1u);
1210 EXPECT_EQ(clock_b.ref_count(), 0u);
1211 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1212
1213 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1214 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1215 EXPECT_EQ(selector_c_test_data.num_calls,
1216 selector_c_test_data.num_expected_calls);
1217 }
1218
TEST(ClockTree,ClockSelectorUpdateSourceFailure5Blocking)1219 TEST(ClockTree, ClockSelectorUpdateSourceFailure5Blocking) {
1220 TestClockSelectorUpdateSourceFailure5<ElementBlocking>();
1221 }
1222
TEST(ClockTree,ClockSelectorUpdateSourceFailure5NonBlocking)1223 TEST(ClockTree, ClockSelectorUpdateSourceFailure5NonBlocking) {
1224 TestClockSelectorUpdateSourceFailure5<ElementNonBlockingMightFail>();
1225 }
1226
1227 template <typename ElementType>
TestClockSource()1228 static void TestClockSource() {
1229 uint32_t shared_clock_value = 0;
1230 uint32_t exclusive_clock_value = 0;
1231
1232 struct clock_source_state_test_call_data call_data[] = {
1233 {1, ClockOperation::kAcquire},
1234 {4, ClockOperation::kAcquire},
1235 {2, ClockOperation::kAcquire},
1236 {1, ClockOperation::kRelease},
1237 {2, ClockOperation::kRelease},
1238 {4, ClockOperation::kRelease}};
1239
1240 struct clock_source_state_test_data test_data;
1241 INIT_TEST_DATA(test_data, call_data);
1242 ClockTree clock_tree;
1243 pw::Status status;
1244
1245 ClockSourceStateTest<ElementType> clock_a(1, &shared_clock_value, test_data);
1246 ClockSourceStateTest<ElementType> clock_b(2, &shared_clock_value, test_data);
1247 ClockSourceStateTest<ElementType> clock_c(
1248 4, &exclusive_clock_value, test_data);
1249 Element& clock_c_element = clock_c;
1250
1251 EXPECT_EQ(clock_a.ref_count(), 0u);
1252 EXPECT_EQ(clock_b.ref_count(), 0u);
1253 EXPECT_EQ(clock_c.ref_count(), 0u);
1254 EXPECT_EQ(shared_clock_value, 0u);
1255 EXPECT_EQ(exclusive_clock_value, 0u);
1256
1257 status = clock_tree.Acquire(clock_a);
1258 EXPECT_EQ(status.code(), PW_STATUS_OK);
1259 EXPECT_EQ(clock_a.ref_count(), 1u);
1260 EXPECT_EQ(clock_b.ref_count(), 0u);
1261 EXPECT_EQ(clock_c.ref_count(), 0u);
1262 EXPECT_EQ(shared_clock_value, 1u);
1263 EXPECT_EQ(exclusive_clock_value, 0u);
1264
1265 status = clock_tree.Acquire(clock_c_element);
1266 EXPECT_EQ(status.code(), PW_STATUS_OK);
1267 EXPECT_EQ(clock_a.ref_count(), 1u);
1268 EXPECT_EQ(clock_b.ref_count(), 0u);
1269 EXPECT_EQ(clock_c.ref_count(), 1u);
1270 EXPECT_EQ(shared_clock_value, 1u);
1271 EXPECT_EQ(exclusive_clock_value, 4u);
1272
1273 status = clock_tree.Acquire(clock_b);
1274 EXPECT_EQ(status.code(), PW_STATUS_OK);
1275 EXPECT_EQ(clock_a.ref_count(), 1u);
1276 EXPECT_EQ(clock_b.ref_count(), 1u);
1277 EXPECT_EQ(clock_c.ref_count(), 1u);
1278 EXPECT_EQ(shared_clock_value, 3u);
1279 EXPECT_EQ(exclusive_clock_value, 4u);
1280
1281 status = clock_tree.Release(clock_a);
1282 EXPECT_EQ(status.code(), PW_STATUS_OK);
1283 EXPECT_EQ(clock_a.ref_count(), 0u);
1284 EXPECT_EQ(clock_b.ref_count(), 1u);
1285 EXPECT_EQ(clock_c.ref_count(), 1u);
1286 EXPECT_EQ(shared_clock_value, 2u);
1287 EXPECT_EQ(exclusive_clock_value, 4u);
1288
1289 status = clock_tree.Release(clock_b);
1290 EXPECT_EQ(status.code(), PW_STATUS_OK);
1291 EXPECT_EQ(clock_a.ref_count(), 0u);
1292 EXPECT_EQ(clock_b.ref_count(), 0u);
1293 EXPECT_EQ(clock_c.ref_count(), 1u);
1294 EXPECT_EQ(shared_clock_value, 0u);
1295 EXPECT_EQ(exclusive_clock_value, 4u);
1296
1297 status = clock_tree.Release(clock_c_element);
1298 EXPECT_EQ(status.code(), PW_STATUS_OK);
1299 EXPECT_EQ(clock_a.ref_count(), 0u);
1300 EXPECT_EQ(clock_b.ref_count(), 0u);
1301 EXPECT_EQ(clock_c.ref_count(), 0u);
1302 EXPECT_EQ(shared_clock_value, 0u);
1303 EXPECT_EQ(exclusive_clock_value, 0u);
1304
1305 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1306 }
1307
TEST(ClockTree,ClockSourceBlocking)1308 TEST(ClockTree, ClockSourceBlocking) { TestClockSource<ElementBlocking>(); }
1309
TEST(ClockTree,ClockSourceNonBlocking)1310 TEST(ClockTree, ClockSourceNonBlocking) {
1311 TestClockSource<ElementNonBlockingMightFail>();
1312 }
1313
1314 // Validate that no references have been acquired when ClockSource
1315 // fails in `DoEnable`.
1316 template <typename ElementType>
TestFailureAcquire1()1317 static void TestFailureAcquire1() {
1318 struct clock_source_failure_test_call_data clock_call_data[] = {
1319 {ClockOperation::kAcquire, pw::Status::Internal()}};
1320
1321 struct clock_source_failure_test_data clock_test_data;
1322 INIT_TEST_DATA(clock_test_data, clock_call_data);
1323 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1324
1325 const uint32_t kSelector = 41;
1326 struct clock_selector_test_data selector_test_data = {};
1327 ClockSelectorTest<ElementType> clock_selector_b(
1328 clock_a, kSelector, 1, 8, selector_test_data);
1329
1330 ClockTree clock_tree;
1331 pw::Status status;
1332
1333 EXPECT_EQ(clock_a.ref_count(), 0u);
1334 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1335
1336 status = clock_tree.Acquire(clock_selector_b);
1337 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1338 EXPECT_EQ(clock_a.ref_count(), 0u);
1339 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1340
1341 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1342 EXPECT_EQ(selector_test_data.num_calls,
1343 selector_test_data.num_expected_calls);
1344 }
1345
TEST(ClockTree,ClockFailureAcquire1Blocking)1346 TEST(ClockTree, ClockFailureAcquire1Blocking) {
1347 TestFailureAcquire1<ElementBlocking>();
1348 }
1349
TEST(ClockTree,ClockFailureAcquire1NonBlocking)1350 TEST(ClockTree, ClockFailureAcquire1NonBlocking) {
1351 TestFailureAcquire1<ElementNonBlockingMightFail>();
1352 }
1353
1354 // Validate that `ClockSource` reference gets released correctly, when
1355 // dependent clock element fails to enable in `DoEnable`, and that
1356 // `DependentElement` doesn't get enabled if dependent
1357 // clock tree element doesn't get enabled successfully.
1358 template <typename ElementType>
TestFailureAcquire2()1359 static void TestFailureAcquire2() {
1360 struct clock_source_failure_test_call_data clock_call_data[] = {
1361 {ClockOperation::kAcquire, pw::OkStatus()},
1362 {ClockOperation::kRelease, pw::OkStatus()}};
1363
1364 struct clock_source_failure_test_data clock_test_data;
1365 INIT_TEST_DATA(clock_test_data, clock_call_data);
1366 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1367
1368 const uint32_t kSelector = 41;
1369 struct clock_selector_test_call_data selector_call_data[] = {
1370 {kSelector, 1, ClockOperation::kAcquire, pw::Status::Internal()}};
1371
1372 struct clock_selector_test_data selector_test_data;
1373 INIT_TEST_DATA(selector_test_data, selector_call_data);
1374 ClockSelectorTest<ElementType> clock_selector_b(
1375 clock_a, kSelector, 1, 8, selector_test_data);
1376
1377 const uint32_t kClockDividerC = 42;
1378 struct clock_divider_test_data divider_test_data = {};
1379 ClockDividerTest<ElementType> clock_divider_c(
1380 clock_selector_b, kClockDividerC, 4, divider_test_data);
1381
1382 ClockTree clock_tree;
1383 pw::Status status;
1384
1385 EXPECT_EQ(clock_a.ref_count(), 0u);
1386 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1387 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1388
1389 status = clock_tree.Acquire(clock_divider_c);
1390 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1391 EXPECT_EQ(clock_a.ref_count(), 0u);
1392 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1393 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1394
1395 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1396 EXPECT_EQ(selector_test_data.num_calls,
1397 selector_test_data.num_expected_calls);
1398 EXPECT_EQ(divider_test_data.num_calls, divider_test_data.num_expected_calls);
1399 }
1400
TEST(ClockTree,ClockFailureAcquire2Blocking)1401 TEST(ClockTree, ClockFailureAcquire2Blocking) {
1402 TestFailureAcquire2<ElementBlocking>();
1403 }
1404
TEST(ClockTree,ClockFailureAcquire2NonBlocking)1405 TEST(ClockTree, ClockFailureAcquire2NonBlocking) {
1406 TestFailureAcquire2<ElementNonBlockingMightFail>();
1407 }
1408
1409 // Validate that `ClockSource` and `DependentElement` references
1410 // gets released correctly, when dependent clock element fails to enable
1411 // in `DoEnable`.
1412 template <typename ElementType>
TestFailureAcquire3()1413 static void TestFailureAcquire3() {
1414 struct clock_source_failure_test_call_data clock_call_data[] = {
1415 {ClockOperation::kAcquire, pw::OkStatus()},
1416 {ClockOperation::kRelease, pw::OkStatus()}};
1417
1418 struct clock_source_failure_test_data clock_test_data;
1419 INIT_TEST_DATA(clock_test_data, clock_call_data);
1420 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1421
1422 const uint32_t kSelector = 41;
1423 struct clock_selector_test_call_data selector_call_data[] = {
1424 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1425 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1426
1427 struct clock_selector_test_data selector_test_data;
1428 INIT_TEST_DATA(selector_test_data, selector_call_data);
1429 ClockSelectorTest<ElementType> clock_selector_b(
1430 clock_a, kSelector, 1, 8, selector_test_data);
1431
1432 const uint32_t kClockDividerC = 42;
1433 struct clock_divider_test_call_data divider_call_data[] = {
1434 {kClockDividerC, 4, ClockOperation::kAcquire, pw::Status::Internal()}};
1435
1436 struct clock_divider_test_data divider_test_data;
1437 INIT_TEST_DATA(divider_test_data, divider_call_data);
1438 ClockDividerTest<ElementType> clock_divider_c(
1439 clock_selector_b, kClockDividerC, 4, divider_test_data);
1440
1441 ClockTree clock_tree;
1442 pw::Status status;
1443
1444 EXPECT_EQ(clock_a.ref_count(), 0u);
1445 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1446 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1447
1448 status = clock_tree.Acquire(clock_divider_c);
1449 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1450 EXPECT_EQ(clock_a.ref_count(), 0u);
1451 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1452 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1453
1454 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1455 EXPECT_EQ(selector_test_data.num_calls,
1456 selector_test_data.num_expected_calls);
1457 EXPECT_EQ(divider_test_data.num_calls, divider_test_data.num_expected_calls);
1458 }
1459
TEST(ClockTree,ClockFailureAcquire3Blocking)1460 TEST(ClockTree, ClockFailureAcquire3Blocking) {
1461 TestFailureAcquire3<ElementBlocking>();
1462 }
1463
TEST(ClockTree,ClockFailureAcquire3NonBlocking)1464 TEST(ClockTree, ClockFailureAcquire3NonBlocking) {
1465 TestFailureAcquire3<ElementNonBlockingMightFail>();
1466 }
1467
1468 // Validate that reference counts are correct when a ClockSource derived class
1469 // fails in `DoDisable` during `Release.
1470 template <typename ElementType>
TestFailureRelease1()1471 static void TestFailureRelease1() {
1472 struct clock_source_failure_test_call_data clock_call_data[] = {
1473 {ClockOperation::kAcquire, pw::OkStatus()},
1474 {ClockOperation::kRelease, pw::Status::Internal()}};
1475
1476 struct clock_source_failure_test_data clock_test_data;
1477 INIT_TEST_DATA(clock_test_data, clock_call_data);
1478 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1479
1480 const uint32_t kSelector = 41;
1481 struct clock_selector_test_call_data selector_call_data[] = {
1482 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1483 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1484
1485 struct clock_selector_test_data selector_test_data;
1486 INIT_TEST_DATA(selector_test_data, selector_call_data);
1487 ClockSelectorTest<ElementType> clock_selector_b(
1488 clock_a, kSelector, 1, 8, selector_test_data);
1489
1490 ClockTree clock_tree;
1491 pw::Status status;
1492
1493 EXPECT_EQ(clock_a.ref_count(), 0u);
1494 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1495
1496 // Acquire initial references
1497 status = clock_tree.Acquire(clock_selector_b);
1498 EXPECT_EQ(status.code(), PW_STATUS_OK);
1499 EXPECT_EQ(clock_a.ref_count(), 1u);
1500 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1501
1502 status = clock_tree.Release(clock_selector_b);
1503 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1504 EXPECT_EQ(clock_a.ref_count(), 1u);
1505 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1506
1507 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1508 EXPECT_EQ(selector_test_data.num_calls,
1509 selector_test_data.num_expected_calls);
1510 }
1511
TEST(ClockTree,ClockFailureRelease1Blocking)1512 TEST(ClockTree, ClockFailureRelease1Blocking) {
1513 TestFailureRelease1<ElementBlocking>();
1514 }
1515
TEST(ClockTree,ClockFailureRelease1NonBlocking)1516 TEST(ClockTree, ClockFailureRelease1NonBlocking) {
1517 TestFailureRelease1<ElementNonBlockingMightFail>();
1518 }
1519
1520 // Validate that the reference is kept alive if a `DoDisable` call
1521 // fails when releasing a reference for a DependentElement derived
1522 // class.
1523 template <typename ElementType>
TestFailureRelease2()1524 static void TestFailureRelease2() {
1525 struct clock_source_failure_test_call_data clock_call_data[] = {
1526 {ClockOperation::kAcquire, pw::OkStatus()}};
1527
1528 struct clock_source_failure_test_data clock_test_data;
1529 INIT_TEST_DATA(clock_test_data, clock_call_data);
1530 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1531
1532 const uint32_t kSelector = 41;
1533 struct clock_selector_test_call_data selector_call_data[] = {
1534 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1535 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()}};
1536
1537 struct clock_selector_test_data selector_test_data;
1538 INIT_TEST_DATA(selector_test_data, selector_call_data);
1539 ClockSelectorTest<ElementType> clock_selector_b(
1540 clock_a, kSelector, 1, 8, selector_test_data);
1541
1542 ClockTree clock_tree;
1543 pw::Status status;
1544
1545 EXPECT_EQ(clock_a.ref_count(), 0u);
1546 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1547
1548 status = clock_tree.Acquire(clock_selector_b);
1549 EXPECT_EQ(status.code(), PW_STATUS_OK);
1550 EXPECT_EQ(clock_a.ref_count(), 1u);
1551 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1552
1553 status = clock_tree.Release(clock_selector_b);
1554 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1555 EXPECT_EQ(clock_a.ref_count(), 1u);
1556 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1557
1558 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1559 EXPECT_EQ(selector_test_data.num_calls,
1560 selector_test_data.num_expected_calls);
1561 }
1562
TEST(ClockTree,ClockFailureRelease2Blocking)1563 TEST(ClockTree, ClockFailureRelease2Blocking) {
1564 TestFailureRelease2<ElementBlocking>();
1565 }
1566
TEST(ClockTree,ClockFailureRelease2NonBlocking)1567 TEST(ClockTree, ClockFailureRelease2NonBlocking) {
1568 TestFailureRelease2<ElementNonBlockingMightFail>();
1569 }
1570
TEST(ClockTree,ElementMayBlock)1571 TEST(ClockTree, ElementMayBlock) {
1572 ClockSourceTest<ElementNonBlockingCannotFail> clock_non_blocking_cannot_fail;
1573 EXPECT_FALSE(clock_non_blocking_cannot_fail.may_block());
1574
1575 ClockSourceTest<ElementNonBlockingMightFail> clock_non_blocking_might_fail;
1576 EXPECT_FALSE(clock_non_blocking_might_fail.may_block());
1577
1578 ClockSourceTest<ElementBlocking> clock_blocking;
1579 EXPECT_TRUE(clock_blocking.may_block());
1580 }
1581
TEST(ClockTree,ClockDividerMayBlock)1582 TEST(ClockTree, ClockDividerMayBlock) {
1583 struct clock_divider_test_data test_data;
1584
1585 ClockSourceTest<ElementNonBlockingCannotFail> clock_non_blocking_cannot_fail;
1586 ClockSourceTest<ElementNonBlockingMightFail> clock_non_blocking_might_fail;
1587 ClockSourceTest<ElementBlocking> clock_blocking;
1588
1589 ClockDividerTest<ElementNonBlockingCannotFail>
1590 clock_divider_non_blocking_cannot_fail(
1591 clock_non_blocking_cannot_fail, 1, 1, test_data);
1592 EXPECT_FALSE(clock_divider_non_blocking_cannot_fail.may_block());
1593
1594 ClockDividerTest<ElementNonBlockingMightFail>
1595 clock_divider_non_blocking_might_fail(
1596 clock_non_blocking_might_fail, 1, 1, test_data);
1597 EXPECT_FALSE(clock_divider_non_blocking_might_fail.may_block());
1598
1599 ClockDividerTest<ElementBlocking> clock_divider_blocking(
1600 clock_blocking, 1, 1, test_data);
1601 EXPECT_TRUE(clock_divider_blocking.may_block());
1602 }
1603
1604 // Validate that the ElementController performs the correct
1605 // clock operations and returns the expected status codes.
1606 template <typename ElementType>
TestElementController()1607 static void TestElementController() {
1608 const uint32_t kSelector = 41;
1609 struct clock_selector_test_call_data call_data[] = {
1610 {kSelector, 2, ClockOperation::kAcquire, pw::Status::Internal()},
1611 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
1612 {kSelector, 7, ClockOperation::kRelease, pw::Status::Internal()},
1613 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()}};
1614
1615 struct clock_selector_test_data test_data;
1616 INIT_TEST_DATA(test_data, call_data);
1617 ClockTree clock_tree;
1618 pw::Status status;
1619
1620 ClockSourceTest<ElementType> clock_a;
1621 ClockSelectorTest<ElementType> clock_selector_b(
1622 clock_a, kSelector, 2, 7, test_data);
1623
1624 EXPECT_EQ(clock_a.ref_count(), 0u);
1625 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1626
1627 // Specify an element controller with valid pointers.
1628 ElementController clock_tree_element_controller(&clock_tree,
1629 &clock_selector_b);
1630
1631 // First acquire call should fail.
1632 status = clock_tree_element_controller.Acquire();
1633 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1634 EXPECT_EQ(clock_a.ref_count(), 0u);
1635 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1636
1637 // Second acquire call should succeed
1638 status = clock_tree_element_controller.Acquire();
1639 EXPECT_EQ(status.code(), PW_STATUS_OK);
1640 EXPECT_EQ(clock_a.ref_count(), 1u);
1641 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1642
1643 // Third acquire call should succeed
1644 status = clock_tree_element_controller.Acquire();
1645 EXPECT_EQ(status.code(), PW_STATUS_OK);
1646 EXPECT_EQ(clock_a.ref_count(), 1u);
1647 EXPECT_EQ(clock_selector_b.ref_count(), 2u);
1648
1649 // First release call should succeed, since this only changes the reference
1650 // count of `clock_selector_b`.
1651 status = clock_tree_element_controller.Release();
1652 EXPECT_EQ(status.code(), PW_STATUS_OK);
1653 EXPECT_EQ(clock_a.ref_count(), 1u);
1654 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1655
1656 // Second release call should fail and not change the reference counts.
1657 status = clock_tree_element_controller.Release();
1658 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1659 EXPECT_EQ(clock_a.ref_count(), 1u);
1660 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1661
1662 // Third release call should succeed.
1663 status = clock_tree_element_controller.Release();
1664 EXPECT_EQ(status.code(), PW_STATUS_OK);
1665 EXPECT_EQ(clock_a.ref_count(), 0u);
1666 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1667
1668 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1669 }
1670
TEST(ClockTree,ElementControllerBlocking)1671 TEST(ClockTree, ElementControllerBlocking) {
1672 TestElementController<ElementBlocking>();
1673 }
1674
TEST(ClockTree,ElementControllerNonBlocking)1675 TEST(ClockTree, ElementControllerNonBlocking) {
1676 TestElementController<ElementNonBlockingMightFail>();
1677 }
1678
1679 // Validate that the ElementController performs clock operations
1680 // for ElementNonBlockingCannotFail elements.
TEST(ClockTree,ElementControllerCannotFail)1681 TEST(ClockTree, ElementControllerCannotFail) {
1682 ClockTree clock_tree;
1683 pw::Status status;
1684
1685 ClockSourceTest<ElementNonBlockingCannotFail> clock_a;
1686
1687 EXPECT_EQ(clock_a.ref_count(), 0u);
1688
1689 // Specify an element controller with valid pointers.
1690 ElementController clock_tree_element_controller(&clock_tree, &clock_a);
1691
1692 // Acquire call should succeed
1693 status = clock_tree_element_controller.Acquire();
1694 EXPECT_EQ(status.code(), PW_STATUS_OK);
1695 EXPECT_EQ(clock_a.ref_count(), 1u);
1696
1697 // Acquire call should succeed
1698 status = clock_tree_element_controller.Acquire();
1699 EXPECT_EQ(status.code(), PW_STATUS_OK);
1700 EXPECT_EQ(clock_a.ref_count(), 2u);
1701
1702 // Release call should succeed.
1703 status = clock_tree_element_controller.Release();
1704 EXPECT_EQ(status.code(), PW_STATUS_OK);
1705 EXPECT_EQ(clock_a.ref_count(), 1u);
1706
1707 // Release call should succeed.
1708 status = clock_tree_element_controller.Release();
1709 EXPECT_EQ(status.code(), PW_STATUS_OK);
1710 EXPECT_EQ(clock_a.ref_count(), 0u);
1711 }
1712
1713 // Validate that the ElementController performs no clock operations
1714 // if not both clock tree and element are specified.
TEST(ClockTree,ElementControllerNoClockOperations)1715 TEST(ClockTree, ElementControllerNoClockOperations) {
1716 ClockTree clock_tree;
1717 pw::Status status;
1718
1719 ClockSourceTest<ElementNonBlockingCannotFail> clock_a;
1720
1721 EXPECT_EQ(clock_a.ref_count(), 0u);
1722
1723 // Specify an element controller with no clock_tree pointer.
1724 ElementController clock_tree_element_controller_no_clock_tree(nullptr,
1725 &clock_a);
1726
1727 // Acquire shouldn't acquire a reference to `clock_a`
1728 // due to the missing `clock_tree`.
1729 status = clock_tree_element_controller_no_clock_tree.Acquire();
1730 EXPECT_EQ(status.code(), PW_STATUS_OK);
1731 EXPECT_EQ(clock_a.ref_count(), 0u);
1732
1733 // Release shouldn't release a reference to `clock_a`
1734 // due to the missing `clock_tree`.
1735 status = clock_tree_element_controller_no_clock_tree.Release();
1736 EXPECT_EQ(status.code(), PW_STATUS_OK);
1737 EXPECT_EQ(clock_a.ref_count(), 0u);
1738
1739 // Specify an element controller with no element pointer.
1740 ElementController clock_tree_element_controller_no_element(&clock_tree,
1741 nullptr);
1742
1743 status = clock_tree_element_controller_no_element.Acquire();
1744 EXPECT_EQ(status.code(), PW_STATUS_OK);
1745
1746 status = clock_tree_element_controller_no_clock_tree.Release();
1747 EXPECT_EQ(status.code(), PW_STATUS_OK);
1748
1749 // Specify an element controller with two null pointers.
1750 ElementController clock_tree_element_controller_nullptrs;
1751
1752 status = clock_tree_element_controller_nullptrs.Acquire();
1753 EXPECT_EQ(status.code(), PW_STATUS_OK);
1754
1755 status = clock_tree_element_controller_nullptrs.Release();
1756 EXPECT_EQ(status.code(), PW_STATUS_OK);
1757 }
1758
1759 // Validate the behavior of the ClockSourceNoOp class
TEST(ClockTree,ClockSourceNoOp)1760 TEST(ClockTree, ClockSourceNoOp) {
1761 const uint32_t kClockDividerA = 23;
1762 const uint32_t kClockDividerB = 42;
1763
1764 struct clock_divider_test_call_data call_data[] = {
1765 {kClockDividerA, 2, ClockOperation::kAcquire, pw::OkStatus()},
1766 {kClockDividerB, 4, ClockOperation::kAcquire, pw::OkStatus()},
1767 {kClockDividerB, 4, ClockOperation::kRelease, pw::OkStatus()},
1768 {kClockDividerA, 2, ClockOperation::kRelease, pw::OkStatus()}};
1769
1770 struct clock_divider_test_data test_data;
1771 INIT_TEST_DATA(test_data, call_data);
1772
1773 ClockTree clock_tree;
1774
1775 ClockSourceNoOp clock_source_no_op;
1776 ClockDividerTest<ElementNonBlockingCannotFail> clock_divider_a(
1777 clock_source_no_op, kClockDividerA, 2, test_data);
1778 ClockDividerTest<ElementNonBlockingCannotFail> clock_divider_b(
1779 clock_source_no_op, kClockDividerB, 4, test_data);
1780
1781 EXPECT_EQ(clock_source_no_op.ref_count(), 0u);
1782 EXPECT_EQ(clock_divider_a.ref_count(), 0u);
1783 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1784
1785 clock_tree.Acquire(clock_divider_a);
1786 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1787 EXPECT_EQ(clock_divider_a.ref_count(), 1u);
1788 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1789
1790 clock_tree.Acquire(clock_divider_a);
1791 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1792 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1793 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1794
1795 clock_tree.Acquire(clock_divider_b);
1796 EXPECT_EQ(clock_source_no_op.ref_count(), 2u);
1797 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1798 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
1799
1800 clock_tree.Release(clock_divider_b);
1801 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1802 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1803 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1804
1805 clock_tree.Release(clock_divider_a);
1806 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1807 EXPECT_EQ(clock_divider_a.ref_count(), 1u);
1808 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1809
1810 clock_tree.Release(clock_divider_a);
1811 EXPECT_EQ(clock_source_no_op.ref_count(), 0u);
1812 EXPECT_EQ(clock_divider_a.ref_count(), 0u);
1813 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1814
1815 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1816 }
1817
1818 } // namespace
1819 } // namespace pw::clock_tree
1820