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