Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: remoting/protocol/client_video_dispatcher_unittest.cc

Issue 850983002: Implement video frame acknowledgements in the chromoting protocol. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/protocol/client_video_dispatcher.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "remoting/base/constants.h"
10 #include "remoting/proto/video.pb.h"
11 #include "remoting/protocol/fake_session.h"
12 #include "remoting/protocol/fake_stream_socket.h"
13 #include "remoting/protocol/message_serialization.h"
14 #include "remoting/protocol/video_stub.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16
17 using testing::_;
18
19 namespace remoting {
20 namespace protocol {
21
22 class MockChannelEventHandler : public ChannelDispatcherBase::EventHandler {
23 public:
24 MockChannelEventHandler() {}
25 ~MockChannelEventHandler() override {}
26
27 MOCK_METHOD1(OnChannelInitialized,
28 void(ChannelDispatcherBase* channel_dispatcher));
29 MOCK_METHOD2(OnChannelError,
30 void(ChannelDispatcherBase* channel_dispatcher,
31 ErrorCode error));
32 };
33
34 class ClientVideoDispatcherTest : public testing::Test, public VideoStub {
35 public:
36 ClientVideoDispatcherTest()
37 : dispatcher_(this),
38 parser_(base::Bind(&ClientVideoDispatcherTest::OnVideoAck,
39 base::Unretained(this)),
40 &reader_) {}
41
42 void Initialize(int version) {
Wez 2015/01/21 01:35:39 nit: InitializeWithProtocolVersion?
Sergey Ulanov 2015/01/29 01:33:28 Done.
43 EXPECT_CALL(event_handler_, OnChannelInitialized(_));
Wez 2015/01/21 01:35:39 Having this expectation in here immediately follow
Sergey Ulanov 2015/01/29 01:33:28 Done.
44 dispatcher_.Init(&session_,
45 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, version,
46 ChannelConfig::CODEC_UNDEFINED),
47 &event_handler_);
48 message_loop_.RunUntilIdle();
49 host_socket_.PairWith(
50 session_.fake_channel_factory().GetFakeChannel(kVideoChannelName));
51 reader_.StartReading(&host_socket_);
52 writer_.Init(&host_socket_, BufferedSocketWriter::WriteFailedCallback());
53 }
54
55 // VideoStub interface.
56 void ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet,
57 const base::Closure& done) {
Wez 2015/01/21 01:35:39 Why is ChannelEventHandler a mock but VideoStub a
Sergey Ulanov 2015/01/29 01:33:29 Removed MockChannelEventHandler.
58 video_packet_ = video_packet.Pass();
59 packet_processed_closure_ = done;
60 }
61
62 protected:
63 void OnVideoAck(scoped_ptr<VideoAck> ack, const base::Closure& done) {
64 ack_message_ = ack.Pass();
65 done.Run();
66 }
67
68 base::MessageLoop message_loop_;
69
70 MockChannelEventHandler event_handler_;
71 ClientVideoDispatcher dispatcher_;
72 FakeSession session_;
73 FakeStreamSocket host_socket_;
74 MessageReader reader_;
75 ProtobufMessageParser<VideoAck> parser_;
76 BufferedSocketWriter writer_;
Wez 2015/01/21 01:35:39 nit: Can you break these up a bit to separate out
Sergey Ulanov 2015/01/29 01:33:29 Done.
77
78 scoped_ptr<VideoPacket> video_packet_;
79 base::Closure packet_processed_closure_;
80
81 scoped_ptr<VideoAck> ack_message_;
82 };
83
84 // Verify that acks are not sent for older versions of the protocol.
85 TEST_F(ClientVideoDispatcherTest, WithoutAcks) {
Wez 2015/01/21 01:35:39 nit: Add a basic test to verify just that parsed V
Sergey Ulanov 2015/01/29 01:33:28 This test already verifies it. Updated the comment
86 int kTestFrameId = 3;
87
88 Initialize(kDefaultStreamVersion);
89
90 VideoPacket packet;
91 packet.set_data(std::string());
92 packet.set_frame_id(kTestFrameId);
93
94 // Send a VideoPacket and verify that the client receives it.
95 writer_.Write(SerializeAndFrameMessage(packet), base::Closure());
96 message_loop_.RunUntilIdle();
Wez 2015/01/21 01:35:39 IIUC the New Way is: RunLoop().RunUntilIdle() fo
Sergey Ulanov 2015/01/29 01:33:28 Done.
97 ASSERT_TRUE(video_packet_);
Wez 2015/01/21 01:35:39 EXPECT_TRUE
Sergey Ulanov 2015/01/29 01:33:28 Done.
98
99 packet_processed_closure_.Run();
100 message_loop_.RunUntilIdle();
101
102 // Ack should never be sent for this version of the protocol.
103 ASSERT_FALSE(ack_message_);
Wez 2015/01/21 01:35:39 EXPECT_FALSE
Sergey Ulanov 2015/01/29 01:33:29 Done.
104 }
105
106 // Verifies that the dispatchers sends Ack message with correct rendering delay.
Wez 2015/01/21 01:35:39 s/dispatchers/dispatcher
Sergey Ulanov 2015/01/29 01:33:28 Done.
107 TEST_F(ClientVideoDispatcherTest, WithAcks) {
108 int kTestFrameId = 3;
109
110 Initialize(kVideoWithAckStreamVersion);
111
112 VideoPacket packet;
113 packet.set_data(std::string());
114 packet.set_frame_id(kTestFrameId);
115
116 // Send a VideoPacket and verify that the client receives it.
117 base::TimeTicks write_started_time = base::TimeTicks::Now();
118 writer_.Write(SerializeAndFrameMessage(packet), base::Closure());
119 message_loop_.RunUntilIdle();
120 ASSERT_TRUE(video_packet_);
Wez 2015/01/21 01:35:39 EXPECT_TRUE
Sergey Ulanov 2015/01/29 01:33:28 Done.
121
122 // Ack should only be sent after the packet is processed.
123 ASSERT_FALSE(ack_message_);
124
125 // Simulate frame render delay.
126 base::TimeTicks render_started_time = base::TimeTicks::Now();
127 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
128 base::TimeDelta render_delay_min =
129 base::TimeTicks::Now() - render_started_time;
130
131 packet_processed_closure_.Run();
Wez 2015/01/21 01:35:39 Comment this, e.g. "Fake completion of video packe
Sergey Ulanov 2015/01/29 01:33:28 Done.
132 base::TimeDelta render_delay_max =
133 base::TimeTicks::Now() - write_started_time;
Wez 2015/01/21 01:35:39 nit: Could we use a base::TickTimer "seam" to allo
Sergey Ulanov 2015/01/29 01:33:29 There are two problems with base::TickClock 1. It'
134
135 message_loop_.RunUntilIdle();
136 ASSERT_TRUE(ack_message_);
137 EXPECT_EQ(kTestFrameId, ack_message_->frame_id());
138
139 // Verify that rendering latency is reported correctly.
140 base::TimeDelta render_delay =
141 base::TimeDelta::FromMicroseconds(ack_message_->rendering_delay_us());
142 EXPECT_TRUE(render_delay >= render_delay_min);
143 EXPECT_TRUE(render_delay <= render_delay_max);
144 }
145
146 // Verifies that the dispatcher reports correct read delay in the messages it
147 // receives.
148 TEST_F(ClientVideoDispatcherTest, ReadDelay) {
149 int kTestFrameId = 3;
150
151 Initialize(kVideoWithAckStreamVersion);
152
153 VideoPacket packet;
154 packet.set_data(std::string());
155 packet.set_frame_id(kTestFrameId);
156
157 // Generate buffers for two video frames.
158 scoped_refptr<net::IOBufferWithSize> packet_buffer_1 =
159 SerializeAndFrameMessage(packet);
160 packet.set_frame_id(kTestFrameId + 1);
161 scoped_refptr<net::IOBufferWithSize> packet_buffer_2 =
162 SerializeAndFrameMessage(packet);
163
164 base::TimeTicks send_started_time = base::TimeTicks::Now();
165
166 // First send all data for the first frame and the first byte for the second
167 // one in a single network packet.
Wez 2015/01/21 01:35:39 nit: There's no guarantee that this will result in
Wez 2015/01/21 01:35:39 nit: s/one/frame
Sergey Ulanov 2015/01/29 01:33:29 Done.
Sergey Ulanov 2015/01/29 01:33:29 I think we can make this assumption with the fake
168 scoped_refptr<net::IOBufferWithSize> buffer =
169 new net::IOBufferWithSize(packet_buffer_1->size() + 1);
170 memcpy(buffer->data(), packet_buffer_1->data(), packet_buffer_1->size());
171 memcpy(buffer->data() + packet_buffer_1->size(), packet_buffer_2->data(), 1);
172 writer_.Write(buffer, base::Closure());
173 message_loop_.RunUntilIdle();
174
175 // Verify that the packet was received.
176 ASSERT_TRUE(video_packet_);
Wez 2015/01/21 01:35:39 nit: EXPECT_TRUE here
Sergey Ulanov 2015/01/29 01:33:28 Done.
177 video_packet_.reset();
178 packet_processed_closure_.Run();
179 message_loop_.RunUntilIdle();
180
181 // Verify that the Ack message for the first video frame has time_to_receive
182 // field set to 0, because the whole frame was received in one message.
Wez 2015/01/21 01:35:39 Doesn't that make this test susceptible to flake e
Sergey Ulanov 2015/01/29 01:33:28 No. It's not possible with the current implementat
183 ASSERT_TRUE(ack_message_);
184 EXPECT_EQ(kTestFrameId, ack_message_->frame_id());
185 EXPECT_EQ(0, ack_message_->time_to_receive_us());
186 ack_message_.reset();
187
188 // Simulate networking latency while receiving the second frame.
189 base::TimeTicks network_delay_started_time = base::TimeTicks::Now();
190 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
191 base::TimeDelta time_to_receive_min =
192 base::TimeTicks::Now() - network_delay_started_time;
193
194 // Send the remainder of the second frame.
195 buffer = new net::IOBufferWithSize(packet_buffer_2->size() - 1);
196 memcpy(buffer->data(), packet_buffer_2->data() + 1,
197 packet_buffer_2->size() - 1);
198 writer_.Write(buffer, base::Closure());
199 message_loop_.RunUntilIdle();
200
201 // Verify that the second packet was received.
202 ASSERT_TRUE(video_packet_);
Wez 2015/01/21 01:35:39 nit: EXPECT_TRUE
Sergey Ulanov 2015/01/29 01:33:28 Done.
203 video_packet_.reset();
Wez 2015/01/21 01:35:39 Do you need to reset it here? You're not touching
Sergey Ulanov 2015/01/29 01:33:29 Done.
204 packet_processed_closure_.Run();
205 message_loop_.RunUntilIdle();
206
207 // Verify that we've received Ack for the second frame.
208 ASSERT_TRUE(ack_message_);
209 EXPECT_EQ(kTestFrameId + 1, ack_message_->frame_id());
210
211 // Verify that the dispatcher set correct time_to_receive value.
212 base::TimeDelta time_to_receive =
213 base::TimeDelta::FromMicroseconds(ack_message_->time_to_receive_us());
214 base::TimeDelta time_to_receive_max =
215 base::TimeTicks::Now() - send_started_time;
Wez 2015/01/21 01:35:39 nit: Shouldn't this calculation take place immedia
Sergey Ulanov 2015/01/29 01:33:28 Done.
216 EXPECT_TRUE(time_to_receive >= time_to_receive_min);
217 EXPECT_TRUE(time_to_receive <= time_to_receive_max);
218 }
219
220 } // namespace protocol
221 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698