15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/proto/event.pb.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/proto/internal.pb.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/message_decoder.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "remoting/protocol/message_serialization.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const unsigned int kTestKey = 142; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void AppendMessage(const EventMessage& msg, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* buffer) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contains one encoded message. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBufferWithSize> encoded_msg; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_msg = SerializeAndFrameMessage(msg); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->append(encoded_msg->data(), encoded_msg->size()); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Construct and prepare data in the |output_stream|. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void PrepareData(uint8** buffer, int* size) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contains all encoded messages. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoded_data; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then append 10 update sequences to the data. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 10; ++i) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventMessage msg; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.set_sequence_number(i); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.mutable_key_event()->set_usb_keycode(kTestKey + i); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.mutable_key_event()->set_pressed((i % 2) != 0); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendMessage(msg, &encoded_data); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = encoded_data.length(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buffer = new uint8[*size]; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(*buffer, encoded_data.c_str(), *size); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimulateReadSequence(const int read_sequence[], int sequence_size) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare encoded data for testing. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* test_data; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareData(&test_data, &size); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<uint8[]> memory_deleter(test_data); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then simulate using MessageDecoder to decode variable 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size of encoded data. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first thing to do is to generate a variable size of data. This is done 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by iterating the following array for read sizes. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageDecoder decoder; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then feed the protocol decoder using the above generated data and the 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // read pattern. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<EventMessage*> message_list; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int pos = 0; pos < size;) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE("Input position: " + base::IntToString(pos)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First generate the amount to feed the decoder. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read = std::min(size - pos, read_sequence[pos % sequence_size]); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And then prepare an IOBuffer for feeding it. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(read)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer->data(), test_data + pos, read); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder.AddData(buffer, read); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CompoundBuffer> message(decoder.GetNextMessage()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message.get()) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventMessage* event = new EventMessage(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompoundBufferInputStream stream(message.get()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(event->ParseFromZeroCopyStream(&stream)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_list.push_back(event); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos += read; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then verify the decoded messages. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(10u, message_list.size()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int index = 0; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<EventMessage*>::iterator it = 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_list.begin(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != message_list.end(); ++it) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE("Message " + base::IntToString(index)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventMessage* message = *it; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Partial update stream. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(message->has_key_event()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sergeyu): Don't use index here. Instead store the expected values 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in an array. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kTestKey + index, message->key_event().usb_keycode()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ((index % 2) != 0, message->key_event().pressed()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++index; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&message_list); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MessageDecoderTest, SmallReads) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kReads[] = {1, 2, 3, 1}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimulateReadSequence(kReads, arraysize(kReads)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MessageDecoderTest, LargeReads) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kReads[] = {50, 50, 5}; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimulateReadSequence(kReads, arraysize(kReads)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MessageDecoderTest, EmptyReads) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kReads[] = {4, 0, 50, 0}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimulateReadSequence(kReads, arraysize(kReads)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 126