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) : handler_(handler), end_(end) {}
63
~TestBidiQueueEnd()64 ~TestBidiQueueEnd() {
65 handler_->Clear();
66 }
67
Send(TA * value)68 std::promise<void>* Send(TA* value) {
69 std::promise<void>* promise = new std::promise<void>();
70 handler_->Post(BindOnce(
71 &TestBidiQueueEnd<TA, TB>::handle_send,
72 common::Unretained(this),
73 common::Unretained(value),
74 common::Unretained(promise)));
75 return promise;
76 }
77
Receive()78 std::promise<TB*>* Receive() {
79 std::promise<TB*>* promise = new std::promise<TB*>();
80 handler_->Post(
81 BindOnce(&TestBidiQueueEnd<TA, TB>::handle_receive, common::Unretained(this), common::Unretained(promise)));
82
83 return promise;
84 }
85
handle_send(TA * value,std::promise<void> * promise)86 void handle_send(TA* value, std::promise<void>* promise) {
87 end_->RegisterEnqueue(
88 handler_,
89 Bind(
90 &TestBidiQueueEnd<TA, TB>::handle_register_enqueue,
91 common::Unretained(this),
92 common::Unretained(value),
93 common::Unretained(promise)));
94 }
95
handle_register_enqueue(TA * value,std::promise<void> * promise)96 std::unique_ptr<TA> handle_register_enqueue(TA* value, std::promise<void>* promise) {
97 end_->UnregisterEnqueue();
98 promise->set_value();
99 return std::unique_ptr<TA>(value);
100 }
101
handle_receive(std::promise<TB * > * promise)102 void handle_receive(std::promise<TB*>* promise) {
103 end_->RegisterDequeue(
104 handler_,
105 Bind(
106 &TestBidiQueueEnd<TA, TB>::handle_register_dequeue, common::Unretained(this), common::Unretained(promise)));
107 }
108
handle_register_dequeue(std::promise<TB * > * promise)109 void handle_register_dequeue(std::promise<TB*>* promise) {
110 end_->UnregisterDequeue();
111 promise->set_value(end_->TryDequeue().get());
112 }
113
114 private:
115 Handler* handler_;
116 BidiQueueEnd<TA, TB>* end_;
117 };
118
TEST_F(BidiQueueTest,simple_test)119 TEST_F(BidiQueueTest, simple_test) {
120 BidiQueue<A, B> queue(100);
121 TestBidiQueueEnd<B, A> test_up(queue.GetUpEnd(), up_handler_);
122 TestBidiQueueEnd<A, B> test_down(queue.GetDownEnd(), down_handler_);
123
124 auto sending_b = new B();
125 auto promise_sending_b = test_up.Send(sending_b);
126 promise_sending_b->get_future().wait();
127 auto promise_receive_b = test_down.Receive();
128 EXPECT_EQ(promise_receive_b->get_future().get(), sending_b);
129 delete promise_receive_b;
130 delete promise_sending_b;
131
132 auto sending_a = new A();
133 auto promise_sending_a = test_down.Send(sending_a);
134 promise_sending_a->get_future().wait();
135 auto promise_receive_a = test_up.Receive();
136 EXPECT_EQ(promise_receive_a->get_future().get(), sending_a);
137 delete promise_receive_a;
138 delete promise_sending_a;
139 }
140
141 } // namespace
142 } // namespace common
143 } // namespace bluetooth
144