1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "net/base/io_buffer.h"
#include "remoting/base/multiple_array_input_stream.h"
#include "remoting/proto/internal.pb.h"
#include "remoting/protocol/message_decoder.h"
#include "remoting/protocol/util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
static const int kWidth = 640;
static const int kHeight = 480;
static const std::string kTestData = "Chromoting rockz";
static void AppendMessage(const ChromotingHostMessage& msg,
std::string* buffer) {
// Contains one encoded message.
scoped_refptr<net::IOBufferWithSize> encoded_msg;
encoded_msg = SerializeAndFrameMessage(msg);
buffer->append(encoded_msg->data(), encoded_msg->size());
}
// Construct and prepare data in the |output_stream|.
static void PrepareData(uint8** buffer, int* size) {
// Contains all encoded messages.
std::string encoded_data;
// The first message is InitClient.
ChromotingHostMessage msg;
msg.mutable_init_client()->set_width(kWidth);
msg.mutable_init_client()->set_height(kHeight);
AppendMessage(msg, &encoded_data);
msg.Clear();
// Then append 10 update sequences to the data.
for (int i = 0; i < 10; ++i) {
msg.mutable_begin_update_stream();
AppendMessage(msg, &encoded_data);
msg.Clear();
msg.mutable_update_stream_packet()->mutable_rect_data()->
set_sequence_number(0);
msg.mutable_update_stream_packet()->mutable_rect_data()->
set_data(kTestData);
AppendMessage(msg, &encoded_data);
msg.Clear();
msg.mutable_end_update_stream();
AppendMessage(msg, &encoded_data);
msg.Clear();
}
*size = encoded_data.length();
*buffer = new uint8[*size];
memcpy(*buffer, encoded_data.c_str(), *size);
}
void SimulateReadSequence(const int read_sequence[], int sequence_size) {
// Prepare encoded data for testing.
int size;
uint8* test_data;
PrepareData(&test_data, &size);
scoped_array<uint8> memory_deleter(test_data);
// Then simulate using MessageDecoder to decode variable
// size of encoded data.
// The first thing to do is to generate a variable size of data. This is done
// by iterating the following array for read sizes.
MessageDecoder decoder;
// Then feed the protocol decoder using the above generated data and the
// read pattern.
std::list<ChromotingHostMessage*> message_list;
for (int i = 0; i < size;) {
// First generate the amount to feed the decoder.
int read = std::min(size - i, read_sequence[i % sequence_size]);
// And then prepare an IOBuffer for feeding it.
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(read);
memcpy(buffer->data(), test_data + i, read);
decoder.ParseMessages(buffer, read, &message_list);
i += read;
}
// Then verify the decoded messages.
EXPECT_EQ(31u, message_list.size());
EXPECT_TRUE(message_list.front()->has_init_client());
delete message_list.front();
message_list.pop_front();
int index = 0;
for (std::list<ChromotingHostMessage*>::iterator it =
message_list.begin();
it != message_list.end(); ++it) {
ChromotingHostMessage* message = *it;
int type = index % 3;
++index;
if (type == 0) {
// Begin update stream.
EXPECT_TRUE(message->has_begin_update_stream());
} else if (type == 1) {
// Partial update stream.
EXPECT_TRUE(message->has_update_stream_packet());
EXPECT_EQ(kTestData,
message->update_stream_packet().rect_data().data());
} else if (type == 2) {
// End update stream.
EXPECT_TRUE(message->has_end_update_stream());
}
}
STLDeleteElements(&message_list);
}
TEST(MessageDecoderTest, SmallReads) {
const int kReads[] = {1, 2, 3, 1};
SimulateReadSequence(kReads, arraysize(kReads));
}
TEST(MessageDecoderTest, LargeReads) {
const int kReads[] = {50, 50, 5};
SimulateReadSequence(kReads, arraysize(kReads));
}
TEST(MessageDecoderTest, EmptyReads) {
const int kReads[] = {4, 0, 50, 0};
SimulateReadSequence(kReads, arraysize(kReads));
}
} // namespace remoting
|