• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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