4008586e01a3c1fdab132ee25df831640dce2b35
[iec.git] / src / type3_AndroidCloud / anbox-master / tests / anbox / graphics / buffered_io_stream_tests.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include "anbox/graphics/buffered_io_stream.h"
19
20 #include <chrono>
21
22 #include <gtest/gtest.h>
23 #include <gmock/gmock.h>
24
25 using namespace ::testing;
26
27 namespace {
28 class MockSocketMessenger :
29     public anbox::network::SocketMessenger {
30  public:
31   // anbox::network::SocketMessenger
32   MOCK_CONST_METHOD0(creds, anbox::network::Credentials());
33   MOCK_CONST_METHOD0(local_port, unsigned short());
34   MOCK_METHOD0(set_no_delay, void());
35   MOCK_METHOD0(close, void());
36
37   // anbox::network::MessageSender
38   MOCK_METHOD2(send, void(char const*, size_t));
39   MOCK_METHOD2(send_raw, ssize_t(char const*, size_t));
40
41   // anbox::network::MessageReceiver
42   MOCK_METHOD2(async_receive_msg, void(AnboxReadHandler const&, boost::asio::mutable_buffers_1 const&));
43   MOCK_METHOD1(receive_msg, boost::system::error_code(boost::asio::mutable_buffers_1 const&));
44   MOCK_METHOD0(available_bytes, size_t());
45 };
46 }
47
48 namespace anbox {
49 namespace graphics {
50 TEST(BufferedIOStream, CommitBufferWritesOutToMessenger) {
51   auto messenger = std::make_shared<MockSocketMessenger>();
52   BufferedIOStream stream(messenger);
53
54   const size_t buffer_size{1000};
55   // We will write out the data we get in two junks of half the size
56   // the original buffer has.
57   EXPECT_CALL(*messenger, send_raw(_, buffer_size))
58       .Times(1)
59       .WillOnce(Return(buffer_size/2));
60   EXPECT_CALL(*messenger, send_raw(_, buffer_size/2))
61       .Times(1)
62       .WillOnce(Return(buffer_size/2));
63
64   char *ptr = static_cast<char*>(stream.allocBuffer(buffer_size));
65   ASSERT_NE(ptr, nullptr);
66   ASSERT_EQ(stream.commitBuffer(buffer_size), buffer_size);
67
68   // The BufferedIOStream class works internally with a thread to
69   // write out the actual data to the messenger. As it blocks in
70   // its d'tor for the writer thread to quit we can safely expect
71   // that the messenger will see all data it has to.
72 }
73
74 TEST(BufferedIOStream, WriterContinuesWhenSocketIsBusy) {
75   auto messenger = std::make_shared<MockSocketMessenger>();
76   BufferedIOStream stream(messenger);
77
78   const size_t buffer_size{1000};
79   const size_t first_chunk_size{100};
80   // The writer will check the error code of the send function
81   // and will retry writing the next chunk when it doesn't get
82   // EAGAIN anymore from the sender.
83   EXPECT_CALL(*messenger, send_raw(_, buffer_size))
84       .Times(1)
85       .WillOnce(Return(first_chunk_size));
86   EXPECT_CALL(*messenger, send_raw(_, buffer_size - first_chunk_size))
87       .Times(2)
88       .WillOnce(DoAll(Invoke([](char const*, size_t) { errno = EAGAIN; }), Return(-EAGAIN)))
89       .WillOnce(Return(buffer_size - first_chunk_size));
90
91   char *ptr = static_cast<char*>(stream.allocBuffer(buffer_size));
92   ASSERT_NE(ptr, nullptr);
93   ASSERT_EQ(stream.commitBuffer(buffer_size), buffer_size);
94 }
95
96 TEST(BufferedIOStream, ReadWhenEnoughDataAvailable) {
97   auto messenger = std::make_shared<MockSocketMessenger>();
98   BufferedIOStream stream(messenger);
99
100   Buffer buffer;
101   buffer.push_back(0x12);
102   buffer.push_back(0x34);
103   stream.post_data(std::move(buffer));
104
105   std::uint8_t read_data[1] = {0x0};
106   size_t size = 1;
107   EXPECT_NE(nullptr, stream.read(read_data, &size));
108   EXPECT_EQ(1, size);
109   EXPECT_EQ(0x12, read_data[0]);
110
111   EXPECT_NE(nullptr, stream.read(read_data, &size));
112   EXPECT_EQ(1, size);
113   EXPECT_EQ(0x34, read_data[0]);
114 }
115
116 TEST(BufferedIOStream, ReadWithNoDataAvailable) {
117   auto messenger = std::make_shared<MockSocketMessenger>();
118   BufferedIOStream stream(messenger);
119
120   bool stopped = false;
121   std::thread producer([&](){
122     while (!stopped) {
123       if (stream.needs_data()) {
124         Buffer buffer;
125         buffer.push_back(0x12);
126         buffer.push_back(0x34);
127         stream.post_data(std::move(buffer));
128       }
129       std::this_thread::sleep_for(std::chrono::milliseconds{10});
130     }
131   });
132
133   constexpr size_t size{10};
134   std::uint8_t read_data[size] = {0x0};
135   size_t read = 10;
136   EXPECT_NE(nullptr, stream.read(read_data, &read));
137   EXPECT_EQ(2, read);
138   EXPECT_EQ(0x12, read_data[0]);
139   EXPECT_EQ(0x34, read_data[1]);
140
141   stopped = true;
142   producer.join();
143 }
144 } // namespace graphics
145 } // namespace anbox