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 pw::Status status;
232 };
233
234 struct clock_source_state_test_data {
235 uint32_t num_expected_calls;
236 uint32_t num_calls;
237 struct clock_source_state_test_call_data* data;
238 };
239
240 template <typename ElementType>
241 class ClockSourceStateTest : public ClockSource<ElementType> {
242 public:
ClockSourceStateTest(uint32_t value,uint32_t * clock_state,struct clock_source_state_test_data & test_data)243 constexpr ClockSourceStateTest(uint32_t value,
244 uint32_t* clock_state,
245 struct clock_source_state_test_data& test_data)
246 : value_(value), clock_state_(clock_state), test_data_(test_data) {}
247
248 private:
ValidateClockAction(ClockOperation op)249 pw::Status ValidateClockAction(ClockOperation op) {
250 pw::Status status = pw::Status::OutOfRange();
251 if (test_data_.num_calls < test_data_.num_expected_calls) {
252 uint32_t i = test_data_.num_calls;
253 EXPECT_EQ(test_data_.data[i].value, value_);
254 EXPECT_EQ(test_data_.data[i].op, op);
255 status = test_data_.data[i].status;
256 }
257 test_data_.num_calls++;
258 return status;
259 }
260
DoEnable()261 pw::Status DoEnable() final {
262 PW_TRY(ValidateClockAction(ClockOperation::kAcquire));
263 *clock_state_ |= value_;
264 return pw::OkStatus();
265 }
266
DoDisable()267 pw::Status DoDisable() final {
268 PW_TRY(ValidateClockAction(ClockOperation::kRelease));
269 *clock_state_ &= ~value_;
270 return pw::OkStatus();
271 }
272
273 uint32_t value_;
274 uint32_t* clock_state_;
275 struct clock_source_state_test_data& test_data_;
276 };
277 using ClockSourceStateTestBlocking = ClockSourceStateTest<ElementBlocking>;
278 using ClockSourceStateTestNonBlocking =
279 ClockSourceStateTest<ElementNonBlockingMightFail>;
280
281 template <typename ElementType>
282 class ClockSourceTest : public ClockSource<ElementType> {
283 private:
DoEnable()284 pw::Status DoEnable() final { return pw::OkStatus(); }
285
DoDisable()286 pw::Status DoDisable() final { return pw::OkStatus(); }
287 };
288 using ClockSourceTestBlocking = ClockSourceTest<ElementBlocking>;
289 using ClockSourceTestNonBlocking = ClockSourceTest<ElementNonBlockingMightFail>;
290
291 struct clock_source_failure_test_call_data {
292 ClockOperation op;
293 pw::Status status;
294 };
295
296 struct clock_source_failure_test_data {
297 uint32_t num_expected_calls;
298 uint32_t num_calls;
299 struct clock_source_failure_test_call_data* data;
300 };
301
302 template <typename ElementType>
303 class ClockSourceFailureTest : public ClockSource<ElementType> {
304 public:
ClockSourceFailureTest(struct clock_source_failure_test_data & test_data)305 constexpr ClockSourceFailureTest(
306 struct clock_source_failure_test_data& test_data)
307 : test_data_(test_data) {}
308
309 private:
ValidateClockAction(ClockOperation op)310 pw::Status ValidateClockAction(ClockOperation op) {
311 pw::Status status = pw::Status::OutOfRange();
312 if (test_data_.num_calls < test_data_.num_expected_calls) {
313 uint32_t i = test_data_.num_calls;
314 EXPECT_EQ(test_data_.data[i].op, op);
315 status = test_data_.data[i].status;
316 }
317 test_data_.num_calls++;
318 return status;
319 }
320
DoEnable()321 pw::Status DoEnable() final {
322 return ValidateClockAction(ClockOperation::kAcquire);
323 }
DoDisable()324 pw::Status DoDisable() final {
325 return ValidateClockAction(ClockOperation::kRelease);
326 }
327 struct clock_source_failure_test_data& test_data_;
328 };
329
330 using ClockSourceFailureTestBlocking = ClockSourceFailureTest<ElementBlocking>;
331 using ClockSourceFailureTestNonBlocking =
332 ClockSourceFailureTest<ElementNonBlockingMightFail>;
333
334 template <typename ElementType>
TestClock()335 static void TestClock() {
336 ClockTree clock_tree;
337 pw::Status status;
338 ClockSourceTest<ElementType> clock_a;
339
340 EXPECT_EQ(clock_a.ref_count(), 0u);
341
342 status = clock_tree.Acquire(clock_a);
343 EXPECT_EQ(status.code(), PW_STATUS_OK);
344 EXPECT_EQ(clock_a.ref_count(), 1u);
345
346 status = clock_tree.Acquire(clock_a);
347 EXPECT_EQ(status.code(), PW_STATUS_OK);
348 EXPECT_EQ(clock_a.ref_count(), 2u);
349
350 status = clock_tree.Release(clock_a);
351 EXPECT_EQ(status.code(), PW_STATUS_OK);
352 EXPECT_EQ(clock_a.ref_count(), 1u);
353
354 status = clock_tree.Release(clock_a);
355 EXPECT_EQ(status.code(), PW_STATUS_OK);
356 EXPECT_EQ(clock_a.ref_count(), 0u);
357 }
358
TEST(ClockTree,ClockBlocking)359 TEST(ClockTree, ClockBlocking) { TestClock<ElementBlocking>(); }
360
TEST(ClockTree,ClockNonBlocking)361 TEST(ClockTree, ClockNonBlocking) { TestClock<ElementNonBlockingMightFail>(); }
362
363 // Validate that the correct divider values are getting set.
364 // The `clock_divider_b` doesn't override the `DoDisable` function,
365 // so only the ClockDividerNoDoDisableTest's `DoEnable` method will be called.
366 template <typename ElementType>
TestClockDivider()367 static void TestClockDivider() {
368 const uint32_t kClockDividerB = 23;
369 const uint32_t kClockDividerC = 42;
370
371 struct clock_divider_test_call_data call_data[] = {
372 {kClockDividerB, 2, ClockOperation::kAcquire, pw::OkStatus()},
373 {kClockDividerC, 4, ClockOperation::kAcquire, pw::OkStatus()},
374 {kClockDividerC, 4, ClockOperation::kRelease, pw::OkStatus()}};
375
376 struct clock_divider_test_data test_data;
377 INIT_TEST_DATA(test_data, call_data);
378 ClockTree clock_tree;
379
380 ClockSourceTest<ElementType> clock_a;
381 ClockDividerNoDoDisableTest<ElementType> clock_divider_b(
382 clock_a, kClockDividerB, 2, test_data);
383 ClockDividerTest<ElementType> clock_divider_c(
384 clock_a, kClockDividerC, 4, test_data);
385 ClockDivider& clock_divider_b_abstract = clock_divider_b;
386 Element& clock_divider_b_element = clock_divider_b_abstract.element();
387 pw::Status status;
388
389 EXPECT_EQ(clock_a.ref_count(), 0u);
390 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
391 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
392
393 status = clock_tree.Acquire(clock_divider_b);
394 EXPECT_EQ(status.code(), PW_STATUS_OK);
395 EXPECT_EQ(clock_a.ref_count(), 1u);
396 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
397 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
398
399 status = clock_tree.Acquire(clock_divider_b_element);
400 EXPECT_EQ(status.code(), PW_STATUS_OK);
401 EXPECT_EQ(clock_a.ref_count(), 1u);
402 EXPECT_EQ(clock_divider_b.ref_count(), 2u);
403 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
404
405 status = clock_tree.Acquire(clock_divider_c);
406 EXPECT_EQ(status.code(), PW_STATUS_OK);
407 EXPECT_EQ(clock_a.ref_count(), 2u);
408 EXPECT_EQ(clock_divider_b.ref_count(), 2u);
409 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
410
411 status = clock_tree.Release(clock_divider_b);
412 EXPECT_EQ(status.code(), PW_STATUS_OK);
413 EXPECT_EQ(clock_a.ref_count(), 2u);
414 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
415 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
416
417 // Releasing `clock_divider_b` won't be tracked, since
418 // only the base class `DoDisable` method will be called.
419 status = clock_tree.Release(clock_divider_b_element);
420 EXPECT_EQ(status.code(), PW_STATUS_OK);
421 EXPECT_EQ(clock_a.ref_count(), 1u);
422 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
423 EXPECT_EQ(clock_divider_c.ref_count(), 1u);
424
425 status = clock_tree.Release(clock_divider_c);
426 EXPECT_EQ(status.code(), PW_STATUS_OK);
427 EXPECT_EQ(clock_a.ref_count(), 0u);
428 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
429 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
430
431 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
432 }
433
TEST(ClockTree,DividerBlocking)434 TEST(ClockTree, DividerBlocking) { TestClockDivider<ElementBlocking>(); }
435
TEST(ClockTree,DividerNonBlocking)436 TEST(ClockTree, DividerNonBlocking) {
437 TestClockDivider<ElementNonBlockingMightFail>();
438 }
439
440 // Validate that different divider values can be set.
441 template <typename ElementType>
TestClockDividerSet()442 static void TestClockDividerSet() {
443 const uint32_t kClockDivider = 23;
444
445 struct clock_divider_test_call_data call_data[] = {
446 {kClockDivider, 2, ClockOperation::kAcquire, pw::OkStatus()},
447 {kClockDivider, 4, ClockOperation::kAcquire, pw::OkStatus()},
448 {kClockDivider, 4, ClockOperation::kRelease, pw::OkStatus()},
449 {kClockDivider, 6, ClockOperation::kAcquire, pw::OkStatus()},
450 {kClockDivider, 6, ClockOperation::kRelease, pw::OkStatus()}};
451
452 struct clock_divider_test_data test_data;
453 INIT_TEST_DATA(test_data, call_data);
454 ClockTree clock_tree;
455 pw::Status status;
456
457 ClockSourceTest<ElementType> clock_a;
458 ClockDividerTest<ElementType> clock_divider_b(
459 clock_a, kClockDivider, 2, test_data);
460 ClockDivider& clock_divider_b_abstract = clock_divider_b;
461
462 EXPECT_EQ(clock_a.ref_count(), 0u);
463 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
464
465 status = clock_tree.Acquire(clock_divider_b);
466 EXPECT_EQ(status.code(), PW_STATUS_OK);
467 EXPECT_EQ(clock_a.ref_count(), 1u);
468 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
469
470 status = clock_tree.SetDividerValue(clock_divider_b_abstract, 4);
471 EXPECT_EQ(status.code(), PW_STATUS_OK);
472 EXPECT_EQ(clock_a.ref_count(), 1u);
473 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
474
475 status = clock_tree.Release(clock_divider_b);
476 EXPECT_EQ(status.code(), PW_STATUS_OK);
477 EXPECT_EQ(clock_a.ref_count(), 0u);
478 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
479
480 status = clock_tree.SetDividerValue(clock_divider_b, 6);
481 EXPECT_EQ(status.code(), PW_STATUS_OK);
482 EXPECT_EQ(clock_a.ref_count(), 0u);
483 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
484
485 status = clock_tree.Acquire(clock_divider_b);
486 EXPECT_EQ(status.code(), PW_STATUS_OK);
487 EXPECT_EQ(clock_a.ref_count(), 1u);
488 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
489
490 status = clock_tree.Release(clock_divider_b);
491 EXPECT_EQ(status.code(), PW_STATUS_OK);
492 EXPECT_EQ(clock_a.ref_count(), 0u);
493 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
494
495 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
496 }
497
TEST(ClockTree,ClockDividerSetBlocking)498 TEST(ClockTree, ClockDividerSetBlocking) {
499 TestClockDividerSet<ElementBlocking>();
500 }
501
TEST(ClockTree,ClockDividerSetNonBlocking)502 TEST(ClockTree, ClockDividerSetNonBlocking) {
503 TestClockDividerSet<ElementNonBlockingMightFail>();
504 }
505
506 // Validate that if the `DoEnable` function fails that gets called as part
507 // of a divider update, that the state of the divider doesn't change.
508 template <typename ElementType>
TestClockDividerSetFailure()509 static void TestClockDividerSetFailure() {
510 const uint32_t kClockDivider = 23;
511
512 struct clock_divider_test_call_data call_data[] = {
513 {kClockDivider, 2, ClockOperation::kAcquire, pw::OkStatus()},
514 {kClockDivider, 4, ClockOperation::kAcquire, pw::Status::Internal()},
515 {kClockDivider, 2, ClockOperation::kRelease, pw::OkStatus()}};
516
517 struct clock_divider_test_data test_data;
518 INIT_TEST_DATA(test_data, call_data);
519 ClockTree clock_tree;
520 pw::Status status;
521
522 ClockSourceTest<ElementType> clock_a;
523 ClockDividerTest<ElementType> clock_divider_b(
524 clock_a, kClockDivider, 2, test_data);
525
526 EXPECT_EQ(clock_a.ref_count(), 0u);
527 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
528
529 status = clock_tree.Acquire(clock_divider_b);
530 EXPECT_EQ(status.code(), PW_STATUS_OK);
531 EXPECT_EQ(clock_a.ref_count(), 1u);
532 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
533
534 status = clock_tree.SetDividerValue(clock_divider_b, 4);
535 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
536 EXPECT_EQ(clock_a.ref_count(), 1u);
537 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
538
539 status = clock_tree.Release(clock_divider_b);
540 EXPECT_EQ(status.code(), PW_STATUS_OK);
541 EXPECT_EQ(clock_a.ref_count(), 0u);
542 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
543
544 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
545 }
546
TEST(ClockTree,ClockDividerSetFailureBlocking)547 TEST(ClockTree, ClockDividerSetFailureBlocking) {
548 TestClockDividerSetFailure<ElementBlocking>();
549 }
550
TEST(ClockTree,ClockDividerSetFailureNonBlocking)551 TEST(ClockTree, ClockDividerSetFailureNonBlocking) {
552 TestClockDividerSetFailure<ElementNonBlockingMightFail>();
553 }
554
555 // Validate that a selector enables and disables correctly.
556 template <typename ElementType>
TestClockSelector()557 static void TestClockSelector() {
558 const uint32_t kSelector = 41;
559 struct clock_selector_test_call_data call_data[] = {
560 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
561 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()},
562 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
563 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()}};
564
565 struct clock_selector_test_data test_data;
566 INIT_TEST_DATA(test_data, call_data);
567 ClockTree clock_tree;
568 pw::Status status;
569
570 ClockSourceTest<ElementType> clock_a;
571 ClockSelectorTest<ElementType> clock_selector_b(
572 clock_a, kSelector, 2, 7, test_data);
573 Element& clock_selector_b_element = clock_selector_b;
574
575 EXPECT_EQ(clock_a.ref_count(), 0u);
576 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
577
578 status = clock_tree.Acquire(clock_selector_b);
579 EXPECT_EQ(status.code(), PW_STATUS_OK);
580 EXPECT_EQ(clock_a.ref_count(), 1u);
581 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
582
583 status = clock_tree.Acquire(clock_selector_b_element);
584 EXPECT_EQ(status.code(), PW_STATUS_OK);
585 EXPECT_EQ(clock_a.ref_count(), 1u);
586 EXPECT_EQ(clock_selector_b.ref_count(), 2u);
587
588 status = clock_tree.Release(clock_selector_b);
589 EXPECT_EQ(status.code(), PW_STATUS_OK);
590 EXPECT_EQ(clock_a.ref_count(), 1u);
591 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
592
593 status = clock_tree.Release(clock_selector_b_element);
594 EXPECT_EQ(status.code(), PW_STATUS_OK);
595 EXPECT_EQ(clock_a.ref_count(), 0u);
596 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
597
598 status = clock_tree.Acquire(clock_selector_b);
599 EXPECT_EQ(status.code(), PW_STATUS_OK);
600 EXPECT_EQ(clock_a.ref_count(), 1u);
601 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
602
603 status = clock_tree.Release(clock_selector_b);
604 EXPECT_EQ(status.code(), PW_STATUS_OK);
605 EXPECT_EQ(clock_a.ref_count(), 0u);
606 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
607
608 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
609 }
610
TEST(ClockTree,ClockSelectorBlocking)611 TEST(ClockTree, ClockSelectorBlocking) { TestClockSelector<ElementBlocking>(); }
612
TEST(ClockTree,ClockSelectorNonBlocking)613 TEST(ClockTree, ClockSelectorNonBlocking) {
614 TestClockSelector<ElementNonBlockingMightFail>();
615 }
616
617 // Validate that we can update the source of a selector.
618 template <typename ElementType>
TestClockSelectorUpdateSource()619 static void TestClockSelectorUpdateSource() {
620 const bool kPermitUpdateWhileInUse = true;
621 const bool kProhibitUpdateWhileInUse = false;
622 const uint32_t kSelector = 41;
623 struct clock_selector_test_call_data call_data[] = {
624 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
625 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
626 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
627 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()},
628 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
629 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()},
630 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
631 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
632 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
633 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()}};
634
635 struct clock_selector_test_data test_data;
636 INIT_TEST_DATA(test_data, call_data);
637 ClockTreeSetSource clock_tree;
638 pw::Status status;
639
640 ClockSourceTest<ElementType> clock_a;
641 ClockSourceTest<ElementType> clock_b;
642 ClockSelectorTest<ElementType> clock_selector_c(
643 clock_a, kSelector, 1, 8, test_data);
644
645 EXPECT_EQ(clock_a.ref_count(), 0u);
646 EXPECT_EQ(clock_b.ref_count(), 0u);
647 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
648
649 status = clock_tree.Acquire(clock_selector_c);
650 EXPECT_EQ(status.code(), PW_STATUS_OK);
651 EXPECT_EQ(clock_a.ref_count(), 1u);
652 EXPECT_EQ(clock_b.ref_count(), 0u);
653 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
654
655 // Validate that we cannot change the source when the reference count is held,
656 // while we are prohibited from changing the source with an active reference
657 // count.
658 status = clock_tree.SetSource(
659 clock_selector_c, clock_b, 20, 40, kProhibitUpdateWhileInUse);
660 EXPECT_EQ(status.code(), PW_STATUS_FAILED_PRECONDITION);
661 EXPECT_EQ(clock_a.ref_count(), 1u);
662 EXPECT_EQ(clock_b.ref_count(), 0u);
663 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
664
665 // Validate that we can change the source when the reference count is held,
666 // while we are permitted to change the source with an active reference count.
667 status = clock_tree.SetSource(
668 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
669 EXPECT_EQ(status.code(), PW_STATUS_OK);
670 EXPECT_EQ(clock_a.ref_count(), 0u);
671 EXPECT_EQ(clock_b.ref_count(), 1u);
672 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
673
674 status = clock_tree.Acquire(clock_selector_c);
675 EXPECT_EQ(status.code(), PW_STATUS_OK);
676 EXPECT_EQ(clock_a.ref_count(), 0u);
677 EXPECT_EQ(clock_b.ref_count(), 1u);
678 EXPECT_EQ(clock_selector_c.ref_count(), 2u);
679
680 status = clock_tree.Release(clock_selector_c);
681 EXPECT_EQ(status.code(), PW_STATUS_OK);
682 EXPECT_EQ(clock_a.ref_count(), 0u);
683 EXPECT_EQ(clock_b.ref_count(), 1u);
684 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
685
686 status = clock_tree.Release(clock_selector_c);
687 EXPECT_EQ(status.code(), PW_STATUS_OK);
688 EXPECT_EQ(clock_a.ref_count(), 0u);
689 EXPECT_EQ(clock_b.ref_count(), 0u);
690 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
691
692 // Validate that we are re-enabling clock_b.
693 status = clock_tree.Acquire(clock_selector_c);
694 EXPECT_EQ(status.code(), PW_STATUS_OK);
695 EXPECT_EQ(clock_a.ref_count(), 0u);
696 EXPECT_EQ(clock_b.ref_count(), 1u);
697 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
698
699 status = clock_tree.Release(clock_selector_c);
700 EXPECT_EQ(status.code(), PW_STATUS_OK);
701 EXPECT_EQ(clock_a.ref_count(), 0u);
702 EXPECT_EQ(clock_b.ref_count(), 0u);
703 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
704
705 // Validate that we can change the source when no reference count is held,
706 // while we are prohibited from changing the source with an active reference
707 // count.
708 status = clock_tree.SetSource(
709 clock_selector_c, clock_a, 1, 8, kProhibitUpdateWhileInUse);
710 EXPECT_EQ(status.code(), PW_STATUS_OK);
711 EXPECT_EQ(clock_a.ref_count(), 0u);
712 EXPECT_EQ(clock_b.ref_count(), 0u);
713 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
714
715 // Validate that we are enabling clock_a.
716 status = clock_tree.Acquire(clock_selector_c);
717 EXPECT_EQ(status.code(), PW_STATUS_OK);
718 EXPECT_EQ(clock_a.ref_count(), 1u);
719 EXPECT_EQ(clock_b.ref_count(), 0u);
720 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
721
722 status = clock_tree.Release(clock_selector_c);
723 EXPECT_EQ(status.code(), PW_STATUS_OK);
724 EXPECT_EQ(clock_a.ref_count(), 0u);
725 EXPECT_EQ(clock_b.ref_count(), 0u);
726 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
727
728 // Validate that we can change the source when no reference count is held,
729 // while we are permitted to change the source with an active reference count.
730 status = clock_tree.SetSource(
731 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
732 EXPECT_EQ(status.code(), PW_STATUS_OK);
733 EXPECT_EQ(clock_a.ref_count(), 0u);
734 EXPECT_EQ(clock_b.ref_count(), 0u);
735 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
736
737 // Validate that we are enabling clock_b.
738 status = clock_tree.Acquire(clock_selector_c);
739 EXPECT_EQ(status.code(), PW_STATUS_OK);
740 EXPECT_EQ(clock_a.ref_count(), 0u);
741 EXPECT_EQ(clock_b.ref_count(), 1u);
742 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
743
744 status = clock_tree.Release(clock_selector_c);
745 EXPECT_EQ(status.code(), PW_STATUS_OK);
746 EXPECT_EQ(clock_a.ref_count(), 0u);
747 EXPECT_EQ(clock_b.ref_count(), 0u);
748 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
749 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
750 }
751
TEST(ClockTree,ClockSelectorUpdateSourceBlocking)752 TEST(ClockTree, ClockSelectorUpdateSourceBlocking) {
753 TestClockSelectorUpdateSource<ElementBlocking>();
754 }
755
TEST(ClockTree,ClockSelectorUpdateSourceNonBlocking)756 TEST(ClockTree, ClockSelectorUpdateSourceNonBlocking) {
757 TestClockSelectorUpdateSource<ElementNonBlockingMightFail>();
758 }
759
760 // Validate that `ClockSource` and current configured selector remain
761 // unchanged if updating clock source fails when acquiring reference
762 // to new source.
763 template <typename ElementType>
TestClockSelectorUpdateSourceFailure1()764 static void TestClockSelectorUpdateSourceFailure1() {
765 const bool kPermitUpdateWhileInUse = true;
766
767 struct clock_source_failure_test_call_data clock_a_call_data[] = {
768 {ClockOperation::kAcquire, pw::OkStatus()},
769 {ClockOperation::kRelease, pw::OkStatus()},
770 {ClockOperation::kAcquire, pw::OkStatus()},
771 {ClockOperation::kRelease, pw::OkStatus()}};
772
773 struct clock_source_failure_test_data clock_a_test_data;
774 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
775 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
776 ;
777
778 struct clock_source_failure_test_call_data clock_b_call_data[] = {
779 {ClockOperation::kAcquire, pw::Status::Internal()}};
780
781 struct clock_source_failure_test_data clock_b_test_data;
782 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
783 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
784 ;
785
786 const uint32_t kSelector = 41;
787 struct clock_selector_test_call_data selector_call_data[] = {
788 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
789 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
790 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
791 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
792
793 struct clock_selector_test_data selector_c_test_data;
794 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
795
796 ClockTreeSetSource clock_tree;
797 pw::Status status;
798
799 ClockSelectorTest<ElementType> clock_selector_c(
800 clock_a, kSelector, 1, 8, selector_c_test_data);
801
802 EXPECT_EQ(clock_a.ref_count(), 0u);
803 EXPECT_EQ(clock_b.ref_count(), 0u);
804 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
805
806 status = clock_tree.Acquire(clock_selector_c);
807 EXPECT_EQ(status.code(), PW_STATUS_OK);
808 EXPECT_EQ(clock_a.ref_count(), 1u);
809 EXPECT_EQ(clock_b.ref_count(), 0u);
810 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
811
812 // Try to acquire a reference to the new source, which will fail. Then
813 // validate that everything remained in place, and that the selector
814 // configuration hasn't changed by releasing and reacquiring the
815 // `clock_selector_c`.
816 status = clock_tree.SetSource(
817 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
818 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
819 EXPECT_EQ(clock_a.ref_count(), 1u);
820 EXPECT_EQ(clock_b.ref_count(), 0u);
821 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
822
823 // Release the selector and verify that the correct selector value gets
824 // configured.
825 status = clock_tree.Release(clock_selector_c);
826 EXPECT_EQ(status.code(), PW_STATUS_OK);
827 EXPECT_EQ(clock_a.ref_count(), 0u);
828 EXPECT_EQ(clock_b.ref_count(), 0u);
829 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
830
831 // Acquire and release the selector and verify that the correct selector
832 // values get configured again.
833 status = clock_tree.Acquire(clock_selector_c);
834 EXPECT_EQ(status.code(), PW_STATUS_OK);
835 EXPECT_EQ(clock_a.ref_count(), 1u);
836 EXPECT_EQ(clock_b.ref_count(), 0u);
837 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
838
839 status = clock_tree.Release(clock_selector_c);
840 EXPECT_EQ(status.code(), PW_STATUS_OK);
841 EXPECT_EQ(clock_a.ref_count(), 0u);
842 EXPECT_EQ(clock_b.ref_count(), 0u);
843 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
844
845 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
846 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
847 EXPECT_EQ(selector_c_test_data.num_calls,
848 selector_c_test_data.num_expected_calls);
849 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure1Blocking)850 TEST(ClockTree, ClockSelectorUpdateSourceFailure1Blocking) {
851 TestClockSelectorUpdateSourceFailure1<ElementBlocking>();
852 }
853
TEST(ClockTree,ClockSelectorUpdateSourceFailure1NonBlocking)854 TEST(ClockTree, ClockSelectorUpdateSourceFailure1NonBlocking) {
855 TestClockSelectorUpdateSourceFailure1<ElementNonBlockingMightFail>();
856 }
857
858 // Validate that `ClockSource` and current configured selector remain
859 // unchanged if `DoDisable` call fails of current selector. The
860 // new source reference count should remain unchanged at the end.
861 template <typename ElementType>
TestClockSelectorUpdateSourceFailure2()862 static void TestClockSelectorUpdateSourceFailure2() {
863 const bool kPermitUpdateWhileInUse = true;
864
865 struct clock_source_failure_test_call_data clock_a_call_data[] = {
866 {ClockOperation::kAcquire, pw::OkStatus()},
867 {ClockOperation::kRelease, pw::OkStatus()},
868 {ClockOperation::kAcquire, pw::OkStatus()},
869 {ClockOperation::kRelease, pw::OkStatus()}};
870
871 struct clock_source_failure_test_data clock_a_test_data;
872 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
873 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
874 ;
875
876 struct clock_source_failure_test_call_data clock_b_call_data[] = {
877 {ClockOperation::kAcquire, pw::OkStatus()},
878 {ClockOperation::kRelease, pw::OkStatus()}};
879
880 struct clock_source_failure_test_data clock_b_test_data;
881 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
882 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
883 ;
884
885 const uint32_t kSelector = 41;
886 struct clock_selector_test_call_data selector_call_data[] = {
887 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
888 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()},
889 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
890 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
891 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
892
893 struct clock_selector_test_data selector_c_test_data;
894 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
895
896 ClockTreeSetSource clock_tree;
897 pw::Status status;
898
899 ClockSelectorTest<ElementType> clock_selector_c(
900 clock_a, kSelector, 1, 8, selector_c_test_data);
901
902 EXPECT_EQ(clock_a.ref_count(), 0u);
903 EXPECT_EQ(clock_b.ref_count(), 0u);
904 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
905
906 status = clock_tree.Acquire(clock_selector_c);
907 EXPECT_EQ(status.code(), PW_STATUS_OK);
908 EXPECT_EQ(clock_a.ref_count(), 1u);
909 EXPECT_EQ(clock_b.ref_count(), 0u);
910 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
911
912 // Try to disable the old source, which will fail. Then validate that
913 // everything remained in place, and that the selector configuration hasn't
914 // changed by releasing and reacquiring the `clock_selector_c`.
915 status = clock_tree.SetSource(
916 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
917 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
918 EXPECT_EQ(clock_a.ref_count(), 1u);
919 EXPECT_EQ(clock_b.ref_count(), 0u);
920 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
921
922 // Release the selector and verify that the correct selector value gets
923 // configured.
924 status = clock_tree.Release(clock_selector_c);
925 EXPECT_EQ(status.code(), PW_STATUS_OK);
926 EXPECT_EQ(clock_a.ref_count(), 0u);
927 EXPECT_EQ(clock_b.ref_count(), 0u);
928 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
929
930 // Acquire and release the selector and verify that the correct selector
931 // values get configured again.
932 status = clock_tree.Acquire(clock_selector_c);
933 EXPECT_EQ(status.code(), PW_STATUS_OK);
934 EXPECT_EQ(clock_a.ref_count(), 1u);
935 EXPECT_EQ(clock_b.ref_count(), 0u);
936 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
937
938 status = clock_tree.Release(clock_selector_c);
939 EXPECT_EQ(status.code(), PW_STATUS_OK);
940 EXPECT_EQ(clock_a.ref_count(), 0u);
941 EXPECT_EQ(clock_b.ref_count(), 0u);
942 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
943
944 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
945 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
946 EXPECT_EQ(selector_c_test_data.num_calls,
947 selector_c_test_data.num_expected_calls);
948 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure2Blocking)949 TEST(ClockTree, ClockSelectorUpdateSourceFailure2Blocking) {
950 TestClockSelectorUpdateSourceFailure2<ElementBlocking>();
951 }
952
TEST(ClockTree,ClockSelectorUpdateSourceFailure2NonBlocking)953 TEST(ClockTree, ClockSelectorUpdateSourceFailure2NonBlocking) {
954 TestClockSelectorUpdateSourceFailure2<ElementNonBlockingMightFail>();
955 }
956
957 // Validate that `ClockSource` and current configured selector remain
958 // unchanged if `DoDisable` call fails of current selector.
959 // The `DoDisable` call of the new source will fail as well, so validate
960 // that the new source got enabled as well.
961 template <typename ElementType>
TestClockSelectorUpdateSourceFailure3()962 static void TestClockSelectorUpdateSourceFailure3() {
963 const bool kPermitUpdateWhileInUse = true;
964
965 struct clock_source_failure_test_call_data clock_a_call_data[] = {
966 {ClockOperation::kAcquire, pw::OkStatus()},
967 {ClockOperation::kRelease, pw::OkStatus()},
968 {ClockOperation::kAcquire, pw::OkStatus()},
969 {ClockOperation::kRelease, pw::OkStatus()}};
970
971 struct clock_source_failure_test_data clock_a_test_data;
972 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
973 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
974 ;
975
976 struct clock_source_failure_test_call_data clock_b_call_data[] = {
977 {ClockOperation::kAcquire, pw::OkStatus()},
978 {ClockOperation::kRelease, pw::Status::FailedPrecondition()}};
979
980 struct clock_source_failure_test_data clock_b_test_data;
981 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
982 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
983 ;
984
985 const uint32_t kSelector = 41;
986 struct clock_selector_test_call_data selector_call_data[] = {
987 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
988 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()},
989 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
990 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
991 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
992
993 struct clock_selector_test_data selector_c_test_data;
994 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
995
996 ClockTreeSetSource clock_tree;
997 pw::Status status;
998
999 ClockSelectorTest<ElementType> clock_selector_c(
1000 clock_a, kSelector, 1, 8, selector_c_test_data);
1001
1002 EXPECT_EQ(clock_a.ref_count(), 0u);
1003 EXPECT_EQ(clock_b.ref_count(), 0u);
1004 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1005
1006 status = clock_tree.Acquire(clock_selector_c);
1007 EXPECT_EQ(status.code(), PW_STATUS_OK);
1008 EXPECT_EQ(clock_a.ref_count(), 1u);
1009 EXPECT_EQ(clock_b.ref_count(), 0u);
1010 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1011
1012 // Try to disable the old source, which will fail, and try to disable the new
1013 // source which will fail as well. Then validate that everything remained in
1014 // place, and that the selector configuration hasn't changed by releasing and
1015 // reacquiring the `clock_selector_c`, but also that the new source got
1016 // acquired.
1017 status = clock_tree.SetSource(
1018 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1019 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1020 EXPECT_EQ(clock_a.ref_count(), 1u);
1021 EXPECT_EQ(clock_b.ref_count(), 1u);
1022 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1023
1024 // Release the selector and verify that the correct selector value gets
1025 // configured.
1026 status = clock_tree.Release(clock_selector_c);
1027 EXPECT_EQ(status.code(), PW_STATUS_OK);
1028 EXPECT_EQ(clock_a.ref_count(), 0u);
1029 EXPECT_EQ(clock_b.ref_count(), 1u);
1030 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1031
1032 // Acquire and release the selector and verify that the correct selector
1033 // values get configured again.
1034 status = clock_tree.Acquire(clock_selector_c);
1035 EXPECT_EQ(status.code(), PW_STATUS_OK);
1036 EXPECT_EQ(clock_a.ref_count(), 1u);
1037 EXPECT_EQ(clock_b.ref_count(), 1u);
1038 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1039
1040 status = clock_tree.Release(clock_selector_c);
1041 EXPECT_EQ(status.code(), PW_STATUS_OK);
1042 EXPECT_EQ(clock_a.ref_count(), 0u);
1043 EXPECT_EQ(clock_b.ref_count(), 1u);
1044 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1045
1046 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1047 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1048 EXPECT_EQ(selector_c_test_data.num_calls,
1049 selector_c_test_data.num_expected_calls);
1050 }
TEST(ClockTree,ClockSelectorUpdateSourceFailure3Blocking)1051 TEST(ClockTree, ClockSelectorUpdateSourceFailure3Blocking) {
1052 TestClockSelectorUpdateSourceFailure3<ElementBlocking>();
1053 }
1054
TEST(ClockTree,ClockSelectorUpdateSourceFailure3NonBlocking)1055 TEST(ClockTree, ClockSelectorUpdateSourceFailure3NonBlocking) {
1056 TestClockSelectorUpdateSourceFailure3<ElementNonBlockingMightFail>();
1057 }
1058
1059 // Validate that `ClockSource` gets disabled, if new clock source's `DoEnable`
1060 // call fails.
1061 template <typename ElementType>
TestClockSelectorUpdateSourceFailure4()1062 static void TestClockSelectorUpdateSourceFailure4() {
1063 const bool kPermitUpdateWhileInUse = true;
1064
1065 struct clock_source_failure_test_call_data clock_a_call_data[] = {
1066 {ClockOperation::kAcquire, pw::OkStatus()},
1067 {ClockOperation::kRelease, pw::OkStatus()},
1068 {ClockOperation::kAcquire, pw::OkStatus()},
1069 {ClockOperation::kRelease, pw::OkStatus()}};
1070
1071 struct clock_source_failure_test_data clock_a_test_data;
1072 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
1073 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
1074 ;
1075
1076 struct clock_source_failure_test_call_data clock_b_call_data[] = {
1077 {ClockOperation::kAcquire, pw::OkStatus()},
1078 {ClockOperation::kRelease, pw::OkStatus()}};
1079
1080 struct clock_source_failure_test_data clock_b_test_data;
1081 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
1082 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
1083 ;
1084
1085 const uint32_t kSelector = 41;
1086 struct clock_selector_test_call_data selector_call_data[] = {
1087 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1088 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
1089 {kSelector, 2, ClockOperation::kAcquire, pw::Status::Internal()},
1090 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1091 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1092
1093 struct clock_selector_test_data selector_c_test_data;
1094 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
1095
1096 ClockTreeSetSource clock_tree;
1097 pw::Status status;
1098
1099 ClockSelectorTest<ElementType> clock_selector_c(
1100 clock_a, kSelector, 1, 8, selector_c_test_data);
1101
1102 EXPECT_EQ(clock_a.ref_count(), 0u);
1103 EXPECT_EQ(clock_b.ref_count(), 0u);
1104 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1105
1106 status = clock_tree.Acquire(clock_selector_c);
1107 EXPECT_EQ(status.code(), PW_STATUS_OK);
1108 EXPECT_EQ(clock_a.ref_count(), 1u);
1109 EXPECT_EQ(clock_b.ref_count(), 0u);
1110 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1111
1112 // Try to enable the new source, which will fail. Since the new source failed
1113 // to enable after we disabled the old source, everything should be disabled
1114 // at this point. When we enable the selector again, the old source should get
1115 // re-enabled again.
1116 status = clock_tree.SetSource(
1117 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1118 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1119 EXPECT_EQ(clock_a.ref_count(), 0u);
1120 EXPECT_EQ(clock_b.ref_count(), 0u);
1121 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1122
1123 // Acquire and release the selector and verify that the correct selector
1124 // values get configured again.
1125 status = clock_tree.Acquire(clock_selector_c);
1126 EXPECT_EQ(status.code(), PW_STATUS_OK);
1127 EXPECT_EQ(clock_a.ref_count(), 1u);
1128 EXPECT_EQ(clock_b.ref_count(), 0u);
1129 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1130
1131 status = clock_tree.Release(clock_selector_c);
1132 EXPECT_EQ(status.code(), PW_STATUS_OK);
1133 EXPECT_EQ(clock_a.ref_count(), 0u);
1134 EXPECT_EQ(clock_b.ref_count(), 0u);
1135 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1136
1137 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1138 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1139 EXPECT_EQ(selector_c_test_data.num_calls,
1140 selector_c_test_data.num_expected_calls);
1141 }
1142
TEST(ClockTree,ClockSelectorUpdateSourceFailure4Blocking)1143 TEST(ClockTree, ClockSelectorUpdateSourceFailure4Blocking) {
1144 TestClockSelectorUpdateSourceFailure4<ElementBlocking>();
1145 }
1146
TEST(ClockTree,ClockSelectorUpdateSourceFailure4NonBlocking)1147 TEST(ClockTree, ClockSelectorUpdateSourceFailure4NonBlocking) {
1148 TestClockSelectorUpdateSourceFailure4<ElementNonBlockingMightFail>();
1149 }
1150
1151 // Validate that we try to release `ClockSource` if new clock source gets
1152 // enabled, and that the failure of release has no impact on newly conifgured
1153 // selector setting.
1154 template <typename ElementType>
TestClockSelectorUpdateSourceFailure5()1155 static void TestClockSelectorUpdateSourceFailure5() {
1156 const bool kPermitUpdateWhileInUse = true;
1157
1158 struct clock_source_failure_test_call_data clock_a_call_data[] = {
1159 {ClockOperation::kAcquire, pw::OkStatus()},
1160 {ClockOperation::kRelease, pw::Status::Internal()}};
1161
1162 struct clock_source_failure_test_data clock_a_test_data;
1163 INIT_TEST_DATA(clock_a_test_data, clock_a_call_data);
1164 ClockSourceFailureTest<ElementType> clock_a(clock_a_test_data);
1165 ;
1166
1167 struct clock_source_failure_test_call_data clock_b_call_data[] = {
1168 {ClockOperation::kAcquire, pw::OkStatus()},
1169 {ClockOperation::kRelease, pw::OkStatus()}};
1170
1171 struct clock_source_failure_test_data clock_b_test_data;
1172 INIT_TEST_DATA(clock_b_test_data, clock_b_call_data);
1173 ClockSourceFailureTest<ElementType> clock_b(clock_b_test_data);
1174 ;
1175
1176 const uint32_t kSelector = 41;
1177 struct clock_selector_test_call_data selector_call_data[] = {
1178 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1179 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()},
1180 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
1181 {kSelector, 4, ClockOperation::kRelease, pw::OkStatus()}};
1182
1183 struct clock_selector_test_data selector_c_test_data;
1184 INIT_TEST_DATA(selector_c_test_data, selector_call_data);
1185
1186 ClockTreeSetSource clock_tree;
1187 pw::Status status;
1188
1189 ClockSelectorTest<ElementType> clock_selector_c(
1190 clock_a, kSelector, 1, 8, selector_c_test_data);
1191
1192 EXPECT_EQ(clock_a.ref_count(), 0u);
1193 EXPECT_EQ(clock_b.ref_count(), 0u);
1194 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1195
1196 status = clock_tree.Acquire(clock_selector_c);
1197 EXPECT_EQ(status.code(), PW_STATUS_OK);
1198 EXPECT_EQ(clock_a.ref_count(), 1u);
1199 EXPECT_EQ(clock_b.ref_count(), 0u);
1200 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1201
1202 // Enable the new source, but releasing the old source fails. The new source
1203 // should be active, but the old source will keep its reference.
1204 status = clock_tree.SetSource(
1205 clock_selector_c, clock_b, 2, 4, kPermitUpdateWhileInUse);
1206 EXPECT_EQ(status.code(), PW_STATUS_OK);
1207 EXPECT_EQ(clock_a.ref_count(), 1u);
1208 EXPECT_EQ(clock_b.ref_count(), 1u);
1209 EXPECT_EQ(clock_selector_c.ref_count(), 1u);
1210
1211 status = clock_tree.Release(clock_selector_c);
1212 EXPECT_EQ(status.code(), PW_STATUS_OK);
1213 EXPECT_EQ(clock_a.ref_count(), 1u);
1214 EXPECT_EQ(clock_b.ref_count(), 0u);
1215 EXPECT_EQ(clock_selector_c.ref_count(), 0u);
1216
1217 EXPECT_EQ(clock_a_test_data.num_calls, clock_a_test_data.num_expected_calls);
1218 EXPECT_EQ(clock_b_test_data.num_calls, clock_b_test_data.num_expected_calls);
1219 EXPECT_EQ(selector_c_test_data.num_calls,
1220 selector_c_test_data.num_expected_calls);
1221 }
1222
TEST(ClockTree,ClockSelectorUpdateSourceFailure5Blocking)1223 TEST(ClockTree, ClockSelectorUpdateSourceFailure5Blocking) {
1224 TestClockSelectorUpdateSourceFailure5<ElementBlocking>();
1225 }
1226
TEST(ClockTree,ClockSelectorUpdateSourceFailure5NonBlocking)1227 TEST(ClockTree, ClockSelectorUpdateSourceFailure5NonBlocking) {
1228 TestClockSelectorUpdateSourceFailure5<ElementNonBlockingMightFail>();
1229 }
1230
1231 template <typename ElementType>
TestClockSource()1232 static void TestClockSource() {
1233 uint32_t shared_clock_value = 0;
1234 uint32_t exclusive_clock_value = 0;
1235
1236 struct clock_source_state_test_call_data call_data[] = {
1237 {1, ClockOperation::kAcquire, pw::OkStatus()},
1238 {4, ClockOperation::kAcquire, pw::OkStatus()},
1239 {2, ClockOperation::kAcquire, pw::OkStatus()},
1240 {1, ClockOperation::kRelease, pw::OkStatus()},
1241 {2, ClockOperation::kRelease, pw::OkStatus()},
1242 {4, ClockOperation::kRelease, pw::OkStatus()}};
1243
1244 struct clock_source_state_test_data test_data;
1245 INIT_TEST_DATA(test_data, call_data);
1246 ClockTree clock_tree;
1247 pw::Status status;
1248
1249 ClockSourceStateTest<ElementType> clock_a(1, &shared_clock_value, test_data);
1250 ClockSourceStateTest<ElementType> clock_b(2, &shared_clock_value, test_data);
1251 ClockSourceStateTest<ElementType> clock_c(
1252 4, &exclusive_clock_value, test_data);
1253 Element& clock_c_element = clock_c;
1254
1255 EXPECT_EQ(clock_a.ref_count(), 0u);
1256 EXPECT_EQ(clock_b.ref_count(), 0u);
1257 EXPECT_EQ(clock_c.ref_count(), 0u);
1258 EXPECT_EQ(shared_clock_value, 0u);
1259 EXPECT_EQ(exclusive_clock_value, 0u);
1260
1261 status = clock_tree.Acquire(clock_a);
1262 EXPECT_EQ(status.code(), PW_STATUS_OK);
1263 EXPECT_EQ(clock_a.ref_count(), 1u);
1264 EXPECT_EQ(clock_b.ref_count(), 0u);
1265 EXPECT_EQ(clock_c.ref_count(), 0u);
1266 EXPECT_EQ(shared_clock_value, 1u);
1267 EXPECT_EQ(exclusive_clock_value, 0u);
1268
1269 status = clock_tree.Acquire(clock_c_element);
1270 EXPECT_EQ(status.code(), PW_STATUS_OK);
1271 EXPECT_EQ(clock_a.ref_count(), 1u);
1272 EXPECT_EQ(clock_b.ref_count(), 0u);
1273 EXPECT_EQ(clock_c.ref_count(), 1u);
1274 EXPECT_EQ(shared_clock_value, 1u);
1275 EXPECT_EQ(exclusive_clock_value, 4u);
1276
1277 status = clock_tree.Acquire(clock_b);
1278 EXPECT_EQ(status.code(), PW_STATUS_OK);
1279 EXPECT_EQ(clock_a.ref_count(), 1u);
1280 EXPECT_EQ(clock_b.ref_count(), 1u);
1281 EXPECT_EQ(clock_c.ref_count(), 1u);
1282 EXPECT_EQ(shared_clock_value, 3u);
1283 EXPECT_EQ(exclusive_clock_value, 4u);
1284
1285 status = clock_tree.Release(clock_a);
1286 EXPECT_EQ(status.code(), PW_STATUS_OK);
1287 EXPECT_EQ(clock_a.ref_count(), 0u);
1288 EXPECT_EQ(clock_b.ref_count(), 1u);
1289 EXPECT_EQ(clock_c.ref_count(), 1u);
1290 EXPECT_EQ(shared_clock_value, 2u);
1291 EXPECT_EQ(exclusive_clock_value, 4u);
1292
1293 status = clock_tree.Release(clock_b);
1294 EXPECT_EQ(status.code(), PW_STATUS_OK);
1295 EXPECT_EQ(clock_a.ref_count(), 0u);
1296 EXPECT_EQ(clock_b.ref_count(), 0u);
1297 EXPECT_EQ(clock_c.ref_count(), 1u);
1298 EXPECT_EQ(shared_clock_value, 0u);
1299 EXPECT_EQ(exclusive_clock_value, 4u);
1300
1301 status = clock_tree.Release(clock_c_element);
1302 EXPECT_EQ(status.code(), PW_STATUS_OK);
1303 EXPECT_EQ(clock_a.ref_count(), 0u);
1304 EXPECT_EQ(clock_b.ref_count(), 0u);
1305 EXPECT_EQ(clock_c.ref_count(), 0u);
1306 EXPECT_EQ(shared_clock_value, 0u);
1307 EXPECT_EQ(exclusive_clock_value, 0u);
1308
1309 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1310 }
1311
TEST(ClockTree,ClockSourceBlocking)1312 TEST(ClockTree, ClockSourceBlocking) { TestClockSource<ElementBlocking>(); }
1313
TEST(ClockTree,ClockSourceNonBlocking)1314 TEST(ClockTree, ClockSourceNonBlocking) {
1315 TestClockSource<ElementNonBlockingMightFail>();
1316 }
1317
1318 // Validate that no references have been acquired when ClockSource
1319 // fails in `DoEnable`.
1320 template <typename ElementType>
TestFailureAcquire1()1321 static void TestFailureAcquire1() {
1322 struct clock_source_failure_test_call_data clock_call_data[] = {
1323 {ClockOperation::kAcquire, pw::Status::Internal()}};
1324
1325 struct clock_source_failure_test_data clock_test_data;
1326 INIT_TEST_DATA(clock_test_data, clock_call_data);
1327 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1328
1329 const uint32_t kSelector = 41;
1330 struct clock_selector_test_data selector_test_data = {};
1331 ClockSelectorTest<ElementType> clock_selector_b(
1332 clock_a, kSelector, 1, 8, selector_test_data);
1333
1334 ClockTree clock_tree;
1335 pw::Status status;
1336
1337 EXPECT_EQ(clock_a.ref_count(), 0u);
1338 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1339
1340 status = clock_tree.Acquire(clock_selector_b);
1341 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1342 EXPECT_EQ(clock_a.ref_count(), 0u);
1343 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1344
1345 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1346 EXPECT_EQ(selector_test_data.num_calls,
1347 selector_test_data.num_expected_calls);
1348 }
1349
TEST(ClockTree,ClockFailureAcquire1Blocking)1350 TEST(ClockTree, ClockFailureAcquire1Blocking) {
1351 TestFailureAcquire1<ElementBlocking>();
1352 }
1353
TEST(ClockTree,ClockFailureAcquire1NonBlocking)1354 TEST(ClockTree, ClockFailureAcquire1NonBlocking) {
1355 TestFailureAcquire1<ElementNonBlockingMightFail>();
1356 }
1357
1358 // Validate that `ClockSource` reference gets released correctly, when
1359 // dependent clock element fails to enable in `DoEnable`, and that
1360 // `DependentElement` doesn't get enabled if dependent
1361 // clock tree element doesn't get enabled successfully.
1362 template <typename ElementType>
TestFailureAcquire2()1363 static void TestFailureAcquire2() {
1364 struct clock_source_failure_test_call_data clock_call_data[] = {
1365 {ClockOperation::kAcquire, pw::OkStatus()},
1366 {ClockOperation::kRelease, pw::OkStatus()}};
1367
1368 struct clock_source_failure_test_data clock_test_data;
1369 INIT_TEST_DATA(clock_test_data, clock_call_data);
1370 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1371
1372 const uint32_t kSelector = 41;
1373 struct clock_selector_test_call_data selector_call_data[] = {
1374 {kSelector, 1, ClockOperation::kAcquire, pw::Status::Internal()}};
1375
1376 struct clock_selector_test_data selector_test_data;
1377 INIT_TEST_DATA(selector_test_data, selector_call_data);
1378 ClockSelectorTest<ElementType> clock_selector_b(
1379 clock_a, kSelector, 1, 8, selector_test_data);
1380
1381 const uint32_t kClockDividerC = 42;
1382 struct clock_divider_test_data divider_test_data = {};
1383 ClockDividerTest<ElementType> clock_divider_c(
1384 clock_selector_b, kClockDividerC, 4, divider_test_data);
1385
1386 ClockTree clock_tree;
1387 pw::Status status;
1388
1389 EXPECT_EQ(clock_a.ref_count(), 0u);
1390 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1391 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1392
1393 status = clock_tree.Acquire(clock_divider_c);
1394 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1395 EXPECT_EQ(clock_a.ref_count(), 0u);
1396 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1397 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1398
1399 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1400 EXPECT_EQ(selector_test_data.num_calls,
1401 selector_test_data.num_expected_calls);
1402 EXPECT_EQ(divider_test_data.num_calls, divider_test_data.num_expected_calls);
1403 }
1404
TEST(ClockTree,ClockFailureAcquire2Blocking)1405 TEST(ClockTree, ClockFailureAcquire2Blocking) {
1406 TestFailureAcquire2<ElementBlocking>();
1407 }
1408
TEST(ClockTree,ClockFailureAcquire2NonBlocking)1409 TEST(ClockTree, ClockFailureAcquire2NonBlocking) {
1410 TestFailureAcquire2<ElementNonBlockingMightFail>();
1411 }
1412
1413 // Validate that `ClockSource` and `DependentElement` references
1414 // gets released correctly, when dependent clock element fails to enable
1415 // in `DoEnable`.
1416 template <typename ElementType>
TestFailureAcquire3()1417 static void TestFailureAcquire3() {
1418 struct clock_source_failure_test_call_data clock_call_data[] = {
1419 {ClockOperation::kAcquire, pw::OkStatus()},
1420 {ClockOperation::kRelease, pw::OkStatus()}};
1421
1422 struct clock_source_failure_test_data clock_test_data;
1423 INIT_TEST_DATA(clock_test_data, clock_call_data);
1424 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1425
1426 const uint32_t kSelector = 41;
1427 struct clock_selector_test_call_data selector_call_data[] = {
1428 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1429 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1430
1431 struct clock_selector_test_data selector_test_data;
1432 INIT_TEST_DATA(selector_test_data, selector_call_data);
1433 ClockSelectorTest<ElementType> clock_selector_b(
1434 clock_a, kSelector, 1, 8, selector_test_data);
1435
1436 const uint32_t kClockDividerC = 42;
1437 struct clock_divider_test_call_data divider_call_data[] = {
1438 {kClockDividerC, 4, ClockOperation::kAcquire, pw::Status::Internal()}};
1439
1440 struct clock_divider_test_data divider_test_data;
1441 INIT_TEST_DATA(divider_test_data, divider_call_data);
1442 ClockDividerTest<ElementType> clock_divider_c(
1443 clock_selector_b, kClockDividerC, 4, divider_test_data);
1444
1445 ClockTree clock_tree;
1446 pw::Status status;
1447
1448 EXPECT_EQ(clock_a.ref_count(), 0u);
1449 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1450 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1451
1452 status = clock_tree.Acquire(clock_divider_c);
1453 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1454 EXPECT_EQ(clock_a.ref_count(), 0u);
1455 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1456 EXPECT_EQ(clock_divider_c.ref_count(), 0u);
1457
1458 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1459 EXPECT_EQ(selector_test_data.num_calls,
1460 selector_test_data.num_expected_calls);
1461 EXPECT_EQ(divider_test_data.num_calls, divider_test_data.num_expected_calls);
1462 }
1463
TEST(ClockTree,ClockFailureAcquire3Blocking)1464 TEST(ClockTree, ClockFailureAcquire3Blocking) {
1465 TestFailureAcquire3<ElementBlocking>();
1466 }
1467
TEST(ClockTree,ClockFailureAcquire3NonBlocking)1468 TEST(ClockTree, ClockFailureAcquire3NonBlocking) {
1469 TestFailureAcquire3<ElementNonBlockingMightFail>();
1470 }
1471
1472 // Validate that reference counts are correct when a ClockSource derived class
1473 // fails in `DoDisable` during `Release.
1474 template <typename ElementType>
TestFailureRelease1()1475 static void TestFailureRelease1() {
1476 struct clock_source_failure_test_call_data clock_call_data[] = {
1477 {ClockOperation::kAcquire, pw::OkStatus()},
1478 {ClockOperation::kRelease, pw::Status::Internal()}};
1479
1480 struct clock_source_failure_test_data clock_test_data;
1481 INIT_TEST_DATA(clock_test_data, clock_call_data);
1482 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1483
1484 const uint32_t kSelector = 41;
1485 struct clock_selector_test_call_data selector_call_data[] = {
1486 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1487 {kSelector, 8, ClockOperation::kRelease, pw::OkStatus()}};
1488
1489 struct clock_selector_test_data selector_test_data;
1490 INIT_TEST_DATA(selector_test_data, selector_call_data);
1491 ClockSelectorTest<ElementType> clock_selector_b(
1492 clock_a, kSelector, 1, 8, selector_test_data);
1493
1494 ClockTree clock_tree;
1495 pw::Status status;
1496
1497 EXPECT_EQ(clock_a.ref_count(), 0u);
1498 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1499
1500 // Acquire initial references
1501 status = clock_tree.Acquire(clock_selector_b);
1502 EXPECT_EQ(status.code(), PW_STATUS_OK);
1503 EXPECT_EQ(clock_a.ref_count(), 1u);
1504 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1505
1506 status = clock_tree.Release(clock_selector_b);
1507 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1508 EXPECT_EQ(clock_a.ref_count(), 1u);
1509 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1510
1511 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1512 EXPECT_EQ(selector_test_data.num_calls,
1513 selector_test_data.num_expected_calls);
1514 }
1515
TEST(ClockTree,ClockFailureRelease1Blocking)1516 TEST(ClockTree, ClockFailureRelease1Blocking) {
1517 TestFailureRelease1<ElementBlocking>();
1518 }
1519
TEST(ClockTree,ClockFailureRelease1NonBlocking)1520 TEST(ClockTree, ClockFailureRelease1NonBlocking) {
1521 TestFailureRelease1<ElementNonBlockingMightFail>();
1522 }
1523
1524 // Validate that the reference is kept alive if a `DoDisable` call
1525 // fails when releasing a reference for a DependentElement derived
1526 // class.
1527 template <typename ElementType>
TestFailureRelease2()1528 static void TestFailureRelease2() {
1529 struct clock_source_failure_test_call_data clock_call_data[] = {
1530 {ClockOperation::kAcquire, pw::OkStatus()}};
1531
1532 struct clock_source_failure_test_data clock_test_data;
1533 INIT_TEST_DATA(clock_test_data, clock_call_data);
1534 ClockSourceFailureTest<ElementType> clock_a(clock_test_data);
1535
1536 const uint32_t kSelector = 41;
1537 struct clock_selector_test_call_data selector_call_data[] = {
1538 {kSelector, 1, ClockOperation::kAcquire, pw::OkStatus()},
1539 {kSelector, 8, ClockOperation::kRelease, pw::Status::Internal()}};
1540
1541 struct clock_selector_test_data selector_test_data;
1542 INIT_TEST_DATA(selector_test_data, selector_call_data);
1543 ClockSelectorTest<ElementType> clock_selector_b(
1544 clock_a, kSelector, 1, 8, selector_test_data);
1545
1546 ClockTree clock_tree;
1547 pw::Status status;
1548
1549 EXPECT_EQ(clock_a.ref_count(), 0u);
1550 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1551
1552 status = clock_tree.Acquire(clock_selector_b);
1553 EXPECT_EQ(status.code(), PW_STATUS_OK);
1554 EXPECT_EQ(clock_a.ref_count(), 1u);
1555 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1556
1557 status = clock_tree.Release(clock_selector_b);
1558 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1559 EXPECT_EQ(clock_a.ref_count(), 1u);
1560 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1561
1562 EXPECT_EQ(clock_test_data.num_calls, clock_test_data.num_expected_calls);
1563 EXPECT_EQ(selector_test_data.num_calls,
1564 selector_test_data.num_expected_calls);
1565 }
1566
TEST(ClockTree,ClockFailureRelease2Blocking)1567 TEST(ClockTree, ClockFailureRelease2Blocking) {
1568 TestFailureRelease2<ElementBlocking>();
1569 }
1570
TEST(ClockTree,ClockFailureRelease2NonBlocking)1571 TEST(ClockTree, ClockFailureRelease2NonBlocking) {
1572 TestFailureRelease2<ElementNonBlockingMightFail>();
1573 }
1574
TEST(ClockTree,ElementMayBlock)1575 TEST(ClockTree, ElementMayBlock) {
1576 ClockSourceTest<ElementNonBlockingCannotFail> clock_non_blocking_cannot_fail;
1577 EXPECT_FALSE(clock_non_blocking_cannot_fail.may_block());
1578
1579 ClockSourceTest<ElementNonBlockingMightFail> clock_non_blocking_might_fail;
1580 EXPECT_FALSE(clock_non_blocking_might_fail.may_block());
1581
1582 ClockSourceTest<ElementBlocking> clock_blocking;
1583 EXPECT_TRUE(clock_blocking.may_block());
1584 }
1585
TEST(ClockTree,ClockDividerMayBlock)1586 TEST(ClockTree, ClockDividerMayBlock) {
1587 struct clock_divider_test_data test_data;
1588
1589 ClockSourceTest<ElementNonBlockingCannotFail> clock_non_blocking_cannot_fail;
1590 ClockSourceTest<ElementNonBlockingMightFail> clock_non_blocking_might_fail;
1591 ClockSourceTest<ElementBlocking> clock_blocking;
1592
1593 ClockDividerTest<ElementNonBlockingCannotFail>
1594 clock_divider_non_blocking_cannot_fail(
1595 clock_non_blocking_cannot_fail, 1, 1, test_data);
1596 EXPECT_FALSE(clock_divider_non_blocking_cannot_fail.may_block());
1597
1598 ClockDividerTest<ElementNonBlockingMightFail>
1599 clock_divider_non_blocking_might_fail(
1600 clock_non_blocking_might_fail, 1, 1, test_data);
1601 EXPECT_FALSE(clock_divider_non_blocking_might_fail.may_block());
1602
1603 ClockDividerTest<ElementBlocking> clock_divider_blocking(
1604 clock_blocking, 1, 1, test_data);
1605 EXPECT_TRUE(clock_divider_blocking.may_block());
1606 }
1607
1608 // Validate that the ElementController performs the correct
1609 // clock operations and returns the expected status codes.
1610 template <typename ElementType>
TestElementController()1611 static void TestElementController() {
1612 const uint32_t kSelector = 41;
1613 struct clock_selector_test_call_data call_data[] = {
1614 {kSelector, 2, ClockOperation::kAcquire, pw::Status::Internal()},
1615 {kSelector, 2, ClockOperation::kAcquire, pw::OkStatus()},
1616 {kSelector, 7, ClockOperation::kRelease, pw::Status::Internal()},
1617 {kSelector, 7, ClockOperation::kRelease, pw::OkStatus()}};
1618
1619 struct clock_selector_test_data test_data;
1620 INIT_TEST_DATA(test_data, call_data);
1621 ClockTree clock_tree;
1622 pw::Status status;
1623
1624 ClockSourceTest<ElementType> clock_a;
1625 ClockSelectorTest<ElementType> clock_selector_b(
1626 clock_a, kSelector, 2, 7, test_data);
1627
1628 EXPECT_EQ(clock_a.ref_count(), 0u);
1629 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1630
1631 // Specify an element controller with valid pointers.
1632 ElementController clock_tree_element_controller(&clock_tree,
1633 &clock_selector_b);
1634
1635 // First acquire call should fail.
1636 status = clock_tree_element_controller.Acquire();
1637 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1638 EXPECT_EQ(clock_a.ref_count(), 0u);
1639 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1640
1641 // Second acquire call should succeed
1642 status = clock_tree_element_controller.Acquire();
1643 EXPECT_EQ(status.code(), PW_STATUS_OK);
1644 EXPECT_EQ(clock_a.ref_count(), 1u);
1645 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1646
1647 // Third acquire call should succeed
1648 status = clock_tree_element_controller.Acquire();
1649 EXPECT_EQ(status.code(), PW_STATUS_OK);
1650 EXPECT_EQ(clock_a.ref_count(), 1u);
1651 EXPECT_EQ(clock_selector_b.ref_count(), 2u);
1652
1653 // First release call should succeed, since this only changes the reference
1654 // count of `clock_selector_b`.
1655 status = clock_tree_element_controller.Release();
1656 EXPECT_EQ(status.code(), PW_STATUS_OK);
1657 EXPECT_EQ(clock_a.ref_count(), 1u);
1658 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1659
1660 // Second release call should fail and not change the reference counts.
1661 status = clock_tree_element_controller.Release();
1662 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1663 EXPECT_EQ(clock_a.ref_count(), 1u);
1664 EXPECT_EQ(clock_selector_b.ref_count(), 1u);
1665
1666 // Third release call should succeed.
1667 status = clock_tree_element_controller.Release();
1668 EXPECT_EQ(status.code(), PW_STATUS_OK);
1669 EXPECT_EQ(clock_a.ref_count(), 0u);
1670 EXPECT_EQ(clock_selector_b.ref_count(), 0u);
1671
1672 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1673 }
1674
TEST(ClockTree,ElementControllerBlocking)1675 TEST(ClockTree, ElementControllerBlocking) {
1676 TestElementController<ElementBlocking>();
1677 }
1678
TEST(ClockTree,ElementControllerNonBlocking)1679 TEST(ClockTree, ElementControllerNonBlocking) {
1680 TestElementController<ElementNonBlockingMightFail>();
1681 }
1682
1683 // Validate that the ElementController performs clock operations
1684 // for ElementNonBlockingCannotFail elements.
TEST(ClockTree,ElementControllerCannotFail)1685 TEST(ClockTree, ElementControllerCannotFail) {
1686 ClockTree clock_tree;
1687 pw::Status status;
1688
1689 ClockSourceTest<ElementNonBlockingCannotFail> clock_a;
1690
1691 EXPECT_EQ(clock_a.ref_count(), 0u);
1692
1693 // Specify an element controller with valid pointers.
1694 ElementController clock_tree_element_controller(&clock_tree, &clock_a);
1695
1696 // Acquire call should succeed
1697 status = clock_tree_element_controller.Acquire();
1698 EXPECT_EQ(status.code(), PW_STATUS_OK);
1699 EXPECT_EQ(clock_a.ref_count(), 1u);
1700
1701 // Acquire call should succeed
1702 status = clock_tree_element_controller.Acquire();
1703 EXPECT_EQ(status.code(), PW_STATUS_OK);
1704 EXPECT_EQ(clock_a.ref_count(), 2u);
1705
1706 // Release call should succeed.
1707 status = clock_tree_element_controller.Release();
1708 EXPECT_EQ(status.code(), PW_STATUS_OK);
1709 EXPECT_EQ(clock_a.ref_count(), 1u);
1710
1711 // Release call should succeed.
1712 status = clock_tree_element_controller.Release();
1713 EXPECT_EQ(status.code(), PW_STATUS_OK);
1714 EXPECT_EQ(clock_a.ref_count(), 0u);
1715 }
1716
1717 // Validate that the ElementController performs no clock operations
1718 // if not both clock tree and element are specified.
TEST(ClockTree,ElementControllerNoClockOperations)1719 TEST(ClockTree, ElementControllerNoClockOperations) {
1720 ClockTree clock_tree;
1721 pw::Status status;
1722
1723 ClockSourceTest<ElementNonBlockingCannotFail> clock_a;
1724
1725 EXPECT_EQ(clock_a.ref_count(), 0u);
1726
1727 // Specify an element controller with no clock_tree pointer.
1728 ElementController clock_tree_element_controller_no_clock_tree(nullptr,
1729 &clock_a);
1730
1731 // Acquire shouldn't acquire a reference to `clock_a`
1732 // due to the missing `clock_tree`.
1733 status = clock_tree_element_controller_no_clock_tree.Acquire();
1734 EXPECT_EQ(status.code(), PW_STATUS_OK);
1735 EXPECT_EQ(clock_a.ref_count(), 0u);
1736
1737 // Release shouldn't release a reference to `clock_a`
1738 // due to the missing `clock_tree`.
1739 status = clock_tree_element_controller_no_clock_tree.Release();
1740 EXPECT_EQ(status.code(), PW_STATUS_OK);
1741 EXPECT_EQ(clock_a.ref_count(), 0u);
1742
1743 // Specify an element controller with no element pointer.
1744 ElementController clock_tree_element_controller_no_element(&clock_tree,
1745 nullptr);
1746
1747 status = clock_tree_element_controller_no_element.Acquire();
1748 EXPECT_EQ(status.code(), PW_STATUS_OK);
1749
1750 status = clock_tree_element_controller_no_clock_tree.Release();
1751 EXPECT_EQ(status.code(), PW_STATUS_OK);
1752
1753 // Specify an element controller with two null pointers.
1754 ElementController clock_tree_element_controller_nullptrs;
1755
1756 status = clock_tree_element_controller_nullptrs.Acquire();
1757 EXPECT_EQ(status.code(), PW_STATUS_OK);
1758
1759 status = clock_tree_element_controller_nullptrs.Release();
1760 EXPECT_EQ(status.code(), PW_STATUS_OK);
1761 }
1762
1763 // Validate the behavior of the ClockSourceNoOp class
TEST(ClockTree,ClockSourceNoOp)1764 TEST(ClockTree, ClockSourceNoOp) {
1765 const uint32_t kClockDividerA = 23;
1766 const uint32_t kClockDividerB = 42;
1767
1768 struct clock_divider_test_call_data call_data[] = {
1769 {kClockDividerA, 2, ClockOperation::kAcquire, pw::OkStatus()},
1770 {kClockDividerB, 4, ClockOperation::kAcquire, pw::OkStatus()},
1771 {kClockDividerB, 4, ClockOperation::kRelease, pw::OkStatus()},
1772 {kClockDividerA, 2, ClockOperation::kRelease, pw::OkStatus()}};
1773
1774 struct clock_divider_test_data test_data;
1775 INIT_TEST_DATA(test_data, call_data);
1776
1777 ClockTree clock_tree;
1778
1779 ClockSourceNoOp clock_source_no_op;
1780 ClockDividerTest<ElementNonBlockingCannotFail> clock_divider_a(
1781 clock_source_no_op, kClockDividerA, 2, test_data);
1782 ClockDividerTest<ElementNonBlockingCannotFail> clock_divider_b(
1783 clock_source_no_op, kClockDividerB, 4, test_data);
1784
1785 EXPECT_EQ(clock_source_no_op.ref_count(), 0u);
1786 EXPECT_EQ(clock_divider_a.ref_count(), 0u);
1787 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1788
1789 clock_tree.Acquire(clock_divider_a);
1790 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1791 EXPECT_EQ(clock_divider_a.ref_count(), 1u);
1792 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1793
1794 clock_tree.Acquire(clock_divider_a);
1795 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1796 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1797 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1798
1799 clock_tree.Acquire(clock_divider_b);
1800 EXPECT_EQ(clock_source_no_op.ref_count(), 2u);
1801 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1802 EXPECT_EQ(clock_divider_b.ref_count(), 1u);
1803
1804 clock_tree.Release(clock_divider_b);
1805 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1806 EXPECT_EQ(clock_divider_a.ref_count(), 2u);
1807 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1808
1809 clock_tree.Release(clock_divider_a);
1810 EXPECT_EQ(clock_source_no_op.ref_count(), 1u);
1811 EXPECT_EQ(clock_divider_a.ref_count(), 1u);
1812 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1813
1814 clock_tree.Release(clock_divider_a);
1815 EXPECT_EQ(clock_source_no_op.ref_count(), 0u);
1816 EXPECT_EQ(clock_divider_a.ref_count(), 0u);
1817 EXPECT_EQ(clock_divider_b.ref_count(), 0u);
1818
1819 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1820 }
1821
1822 // Validate that AcquireWith acquires the element_with during
1823 // acquisition of element.
TEST(ClockTree,AcquireWith)1824 TEST(ClockTree, AcquireWith) {
1825 uint32_t element_with_value = 0;
1826 uint32_t element_value = 0;
1827
1828 // The order of acquisitions validates that we are
1829 // acquiring `element_with` before acquring `element`,
1830 // and releasing `element_with` after acquiring `element`.
1831 struct clock_source_state_test_call_data call_data[] = {
1832 // AcquireWith(element, element_with)
1833 {1, ClockOperation::kAcquire, pw::OkStatus()},
1834 {2, ClockOperation::kAcquire, pw::OkStatus()},
1835 {1, ClockOperation::kRelease, pw::OkStatus()},
1836 // Release(element)
1837 {2, ClockOperation::kRelease, pw::OkStatus()},
1838 // Acquire(element_with)
1839 {1, ClockOperation::kAcquire, pw::OkStatus()},
1840 // AcquireWith(element, element_with)
1841 {2, ClockOperation::kAcquire, pw::OkStatus()}};
1842
1843 struct clock_source_state_test_data test_data;
1844 INIT_TEST_DATA(test_data, call_data);
1845
1846 ClockSourceStateTestBlocking clock_element_with(
1847 1, &element_with_value, test_data);
1848 ClockSourceStateTestBlocking clock_element(2, &element_value, test_data);
1849
1850 ClockTree clock_tree;
1851 pw::Status status;
1852
1853 EXPECT_EQ(clock_element.ref_count(), 0u);
1854 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1855
1856 status = clock_tree.AcquireWith(clock_element, clock_element_with);
1857 EXPECT_EQ(status.code(), PW_STATUS_OK);
1858 EXPECT_EQ(clock_element.ref_count(), 1u);
1859 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1860 EXPECT_EQ(element_with_value, 0u);
1861 EXPECT_EQ(element_value, 2u);
1862
1863 status = clock_tree.Release(clock_element);
1864 EXPECT_EQ(status.code(), PW_STATUS_OK);
1865 EXPECT_EQ(clock_element.ref_count(), 0u);
1866 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1867 EXPECT_EQ(element_with_value, 0u);
1868 EXPECT_EQ(element_value, 0u);
1869
1870 status = clock_tree.Acquire(clock_element_with);
1871 EXPECT_EQ(status.code(), PW_STATUS_OK);
1872 EXPECT_EQ(clock_element.ref_count(), 0u);
1873 EXPECT_EQ(clock_element_with.ref_count(), 1u);
1874 EXPECT_EQ(element_with_value, 1u);
1875 EXPECT_EQ(element_value, 0u);
1876
1877 status = clock_tree.AcquireWith(clock_element, clock_element_with);
1878 EXPECT_EQ(status.code(), PW_STATUS_OK);
1879 EXPECT_EQ(clock_element.ref_count(), 1u);
1880 EXPECT_EQ(clock_element_with.ref_count(), 1u);
1881 EXPECT_EQ(element_with_value, 1u);
1882 EXPECT_EQ(element_value, 2u);
1883
1884 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1885 }
1886
TEST(ClockTree,AcquireWithFailure1)1887 TEST(ClockTree, AcquireWithFailure1) {
1888 uint32_t element_with_value = 0;
1889 uint32_t element_value = 0;
1890
1891 struct clock_source_state_test_call_data call_data[] = {
1892 // AcquireWith(element, element_with)
1893 {1, ClockOperation::kAcquire, pw::Status::Internal()}};
1894
1895 struct clock_source_state_test_data test_data;
1896 INIT_TEST_DATA(test_data, call_data);
1897
1898 ClockSourceStateTestBlocking clock_element_with(
1899 1, &element_with_value, test_data);
1900 ClockSourceStateTestBlocking clock_element(2, &element_value, test_data);
1901
1902 ClockTree clock_tree;
1903 pw::Status status;
1904
1905 EXPECT_EQ(clock_element.ref_count(), 0u);
1906 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1907
1908 status = clock_tree.AcquireWith(clock_element, clock_element_with);
1909 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1910 EXPECT_EQ(clock_element.ref_count(), 0u);
1911 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1912 EXPECT_EQ(element_with_value, 0u);
1913 EXPECT_EQ(element_value, 0u);
1914
1915 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1916 }
1917
TEST(ClockTree,AcquireWithFailure2)1918 TEST(ClockTree, AcquireWithFailure2) {
1919 uint32_t element_with_value = 0;
1920 uint32_t element_value = 0;
1921
1922 struct clock_source_state_test_call_data call_data[] = {
1923 // AcquireWith(element, element_with)
1924 {1, ClockOperation::kAcquire, pw::OkStatus()},
1925 {2, ClockOperation::kAcquire, pw::Status::Internal()},
1926 {1, ClockOperation::kRelease, pw::OkStatus()}};
1927
1928 struct clock_source_state_test_data test_data;
1929 INIT_TEST_DATA(test_data, call_data);
1930
1931 ClockSourceStateTestBlocking clock_element_with(
1932 1, &element_with_value, test_data);
1933 ClockSourceStateTestBlocking clock_element(2, &element_value, test_data);
1934
1935 ClockTree clock_tree;
1936 pw::Status status;
1937
1938 EXPECT_EQ(clock_element.ref_count(), 0u);
1939 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1940
1941 status = clock_tree.AcquireWith(clock_element, clock_element_with);
1942 EXPECT_EQ(status.code(), PW_STATUS_INTERNAL);
1943 EXPECT_EQ(clock_element.ref_count(), 0u);
1944 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1945 EXPECT_EQ(element_with_value, 0u);
1946 EXPECT_EQ(element_value, 0u);
1947
1948 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1949 }
1950
TEST(ClockTree,AcquireWithFailure3)1951 TEST(ClockTree, AcquireWithFailure3) {
1952 uint32_t element_with_value = 0;
1953 uint32_t element_value = 0;
1954
1955 struct clock_source_state_test_call_data call_data[] = {
1956 // AcquireWith(element, element_with)
1957 {1, ClockOperation::kAcquire, pw::OkStatus()},
1958 {2, ClockOperation::kAcquire, pw::OkStatus()},
1959 {1, ClockOperation::kRelease, pw::Status::Internal()}};
1960
1961 struct clock_source_state_test_data test_data;
1962 INIT_TEST_DATA(test_data, call_data);
1963
1964 ClockSourceStateTestBlocking clock_element_with(
1965 1, &element_with_value, test_data);
1966 ClockSourceStateTestBlocking clock_element(2, &element_value, test_data);
1967
1968 ClockTree clock_tree;
1969 pw::Status status;
1970
1971 EXPECT_EQ(clock_element.ref_count(), 0u);
1972 EXPECT_EQ(clock_element_with.ref_count(), 0u);
1973
1974 status = clock_tree.AcquireWith(clock_element, clock_element_with);
1975 EXPECT_EQ(status.code(), PW_STATUS_OK);
1976 EXPECT_EQ(clock_element.ref_count(), 1u);
1977 EXPECT_EQ(clock_element_with.ref_count(), 1u);
1978 EXPECT_EQ(element_with_value, 1u);
1979 EXPECT_EQ(element_value, 2u);
1980
1981 EXPECT_EQ(test_data.num_calls, test_data.num_expected_calls);
1982 }
1983 } // namespace
1984 } // namespace pw::clock_tree
1985