1 // Copyright (c) 2011 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.
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "remoting/proto/event.pb.h"
11 #include "remoting/proto/internal.pb.h"
12 #include "remoting/protocol/message_decoder.h"
13 #include "remoting/protocol/message_serialization.h"
14 #include "testing/gtest/include/gtest/gtest.h"
19 static const unsigned int kTestKey
= 142;
21 static void AppendMessage(const EventMessage
& msg
,
22 std::string
* buffer
) {
23 // Contains one encoded message.
24 scoped_refptr
<net::IOBufferWithSize
> encoded_msg
;
25 encoded_msg
= SerializeAndFrameMessage(msg
);
26 buffer
->append(encoded_msg
->data(), encoded_msg
->size());
29 // Construct and prepare data in the |output_stream|.
30 static void PrepareData(uint8
** buffer
, int* size
) {
31 // Contains all encoded messages.
32 std::string encoded_data
;
34 // Then append 10 update sequences to the data.
35 for (int i
= 0; i
< 10; ++i
) {
37 msg
.set_sequence_number(i
);
38 msg
.mutable_key_event()->set_usb_keycode(kTestKey
+ i
);
39 msg
.mutable_key_event()->set_pressed((i
% 2) != 0);
40 AppendMessage(msg
, &encoded_data
);
43 *size
= encoded_data
.length();
44 *buffer
= new uint8
[*size
];
45 memcpy(*buffer
, encoded_data
.c_str(), *size
);
48 void SimulateReadSequence(const int read_sequence
[], int sequence_size
) {
49 // Prepare encoded data for testing.
52 PrepareData(&test_data
, &size
);
53 scoped_ptr
<uint8
[]> memory_deleter(test_data
);
55 // Then simulate using MessageDecoder to decode variable
56 // size of encoded data.
57 // The first thing to do is to generate a variable size of data. This is done
58 // by iterating the following array for read sizes.
59 MessageDecoder decoder
;
61 // Then feed the protocol decoder using the above generated data and the
63 std::list
<EventMessage
*> message_list
;
64 for (int pos
= 0; pos
< size
;) {
65 SCOPED_TRACE("Input position: " + base::IntToString(pos
));
67 // First generate the amount to feed the decoder.
68 int read
= std::min(size
- pos
, read_sequence
[pos
% sequence_size
]);
70 // And then prepare an IOBuffer for feeding it.
71 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(read
));
72 memcpy(buffer
->data(), test_data
+ pos
, read
);
73 decoder
.AddData(buffer
, read
);
75 scoped_ptr
<CompoundBuffer
> message(decoder
.GetNextMessage());
79 EventMessage
* event
= new EventMessage();
80 CompoundBufferInputStream
stream(message
.get());
81 ASSERT_TRUE(event
->ParseFromZeroCopyStream(&stream
));
82 message_list
.push_back(event
);
87 // Then verify the decoded messages.
88 EXPECT_EQ(10u, message_list
.size());
90 unsigned int index
= 0;
91 for (std::list
<EventMessage
*>::iterator it
=
93 it
!= message_list
.end(); ++it
) {
94 SCOPED_TRACE("Message " + base::IntToString(index
));
96 EventMessage
* message
= *it
;
97 // Partial update stream.
98 EXPECT_TRUE(message
->has_key_event());
100 // TODO(sergeyu): Don't use index here. Instead store the expected values
102 EXPECT_EQ(kTestKey
+ index
, message
->key_event().usb_keycode());
103 EXPECT_EQ((index
% 2) != 0, message
->key_event().pressed());
106 STLDeleteElements(&message_list
);
109 TEST(MessageDecoderTest
, SmallReads
) {
110 const int kReads
[] = {1, 2, 3, 1};
111 SimulateReadSequence(kReads
, arraysize(kReads
));
114 TEST(MessageDecoderTest
, LargeReads
) {
115 const int kReads
[] = {50, 50, 5};
116 SimulateReadSequence(kReads
, arraysize(kReads
));
119 TEST(MessageDecoderTest
, EmptyReads
) {
120 const int kReads
[] = {4, 0, 50, 0};
121 SimulateReadSequence(kReads
, arraysize(kReads
));
124 } // namespace protocol
125 } // namespace remoting