1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "common/bidi_queue.h"
18
19 #include <future>
20
21 #include "common/bind.h"
22 #include "gtest/gtest.h"
23 #include "os/handler.h"
24 #include "os/thread.h"
25
26 using ::bluetooth::os::Handler;
27 using ::bluetooth::os::Thread;
28
29 namespace bluetooth {
30 namespace common {
31 namespace {
32
33 class BidiQueueTest : public ::testing::Test {
34 protected:
SetUp()35 void SetUp() override {
36 up_thread_ = new Thread("up_thread", Thread::Priority::NORMAL);
37 up_handler_ = new Handler(up_thread_);
38 down_thread_ = new Thread("down_thread", Thread::Priority::NORMAL);
39 down_handler_ = new Handler(down_thread_);
40 }
41
TearDown()42 void TearDown() override {
43 delete up_handler_;
44 delete up_thread_;
45 delete down_handler_;
46 delete down_thread_;
47 }
48
49 Thread* up_thread_;
50 Handler* up_handler_;
51 Thread* down_thread_;
52 Handler* down_handler_;
53 };
54
55 class A {};
56
57 class B {};
58
59 template <typename TA, typename TB>
60 class TestBidiQueueEnd {
61 public:
TestBidiQueueEnd(BidiQueueEnd<TA,TB> * end,Handler * handler)62 explicit TestBidiQueueEnd(BidiQueueEnd<TA, TB>* end, Handler* handler)
63 : handler_(handler), end_(end) {}
64
~TestBidiQueueEnd()65 ~TestBidiQueueEnd() { handler_->Clear(); }
66
Send(TA * value)67 std::promise<void>* Send(TA* value) {
68 std::promise<void>* promise = new std::promise<void>();
69 handler_->Post(BindOnce(&TestBidiQueueEnd<TA, TB>::handle_send, common::Unretained(this),
70 common::Unretained(value), common::Unretained(promise)));
71 return promise;
72 }
73
Receive()74 std::promise<TB*>* Receive() {
75 std::promise<TB*>* promise = new std::promise<TB*>();
76 handler_->Post(BindOnce(&TestBidiQueueEnd<TA, TB>::handle_receive, common::Unretained(this),
77 common::Unretained(promise)));
78
79 return promise;
80 }
81
handle_send(TA * value,std::promise<void> * promise)82 void handle_send(TA* value, std::promise<void>* promise) {
83 end_->RegisterEnqueue(handler_, Bind(&TestBidiQueueEnd<TA, TB>::handle_register_enqueue,
84 common::Unretained(this), common::Unretained(value),
85 common::Unretained(promise)));
86 }
87
handle_register_enqueue(TA * value,std::promise<void> * promise)88 std::unique_ptr<TA> handle_register_enqueue(TA* value, std::promise<void>* promise) {
89 end_->UnregisterEnqueue();
90 promise->set_value();
91 return std::unique_ptr<TA>(value);
92 }
93
handle_receive(std::promise<TB * > * promise)94 void handle_receive(std::promise<TB*>* promise) {
95 end_->RegisterDequeue(handler_, Bind(&TestBidiQueueEnd<TA, TB>::handle_register_dequeue,
96 common::Unretained(this), common::Unretained(promise)));
97 }
98
handle_register_dequeue(std::promise<TB * > * promise)99 void handle_register_dequeue(std::promise<TB*>* promise) {
100 end_->UnregisterDequeue();
101 promise->set_value(end_->TryDequeue().get());
102 }
103
104 private:
105 Handler* handler_;
106 BidiQueueEnd<TA, TB>* end_;
107 };
108
TEST_F(BidiQueueTest,simple_test)109 TEST_F(BidiQueueTest, simple_test) {
110 BidiQueue<A, B> queue(100);
111 TestBidiQueueEnd<B, A> test_up(queue.GetUpEnd(), up_handler_);
112 TestBidiQueueEnd<A, B> test_down(queue.GetDownEnd(), down_handler_);
113
114 auto sending_b = new B();
115 auto promise_sending_b = test_up.Send(sending_b);
116 promise_sending_b->get_future().wait();
117 auto promise_receive_b = test_down.Receive();
118 EXPECT_EQ(promise_receive_b->get_future().get(), sending_b);
119 delete promise_receive_b;
120 delete promise_sending_b;
121
122 auto sending_a = new A();
123 auto promise_sending_a = test_down.Send(sending_a);
124 promise_sending_a->get_future().wait();
125 auto promise_receive_a = test_up.Receive();
126 EXPECT_EQ(promise_receive_a->get_future().get(), sending_a);
127 delete promise_receive_a;
128 delete promise_sending_a;
129 }
130
131 } // namespace
132 } // namespace common
133 } // namespace bluetooth
134