Home | History | Annotate | Download | only in cast_channel
      1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_framer.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 namespace extensions {
     13 namespace core_api {
     14 namespace cast_channel {
     15 class CastFramerTest : public testing::Test {
     16  public:
     17   CastFramerTest() {}
     18   virtual ~CastFramerTest() {}
     19 
     20   virtual void SetUp() OVERRIDE {
     21     cast_message_.set_protocol_version(CastMessage::CASTV2_1_0);
     22     cast_message_.set_source_id("source");
     23     cast_message_.set_destination_id("destination");
     24     cast_message_.set_namespace_("namespace");
     25     cast_message_.set_payload_type(CastMessage::STRING);
     26     cast_message_.set_payload_utf8("payload");
     27     ASSERT_TRUE(MessageFramer::Serialize(cast_message_, &cast_message_str_));
     28 
     29     buffer_ = new net::GrowableIOBuffer;
     30     buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size());
     31     framer_.reset(new MessageFramer(buffer_.get()));
     32   }
     33 
     34   void WriteToBuffer(const std::string& data) {
     35     memcpy(buffer_->StartOfBuffer(), data.data(), data.size());
     36   }
     37 
     38  protected:
     39   CastMessage cast_message_;
     40   std::string cast_message_str_;
     41   scoped_refptr<net::GrowableIOBuffer> buffer_;
     42   scoped_ptr<MessageFramer> framer_;
     43 };
     44 
     45 TEST_F(CastFramerTest, TestMessageFramerCompleteMessage) {
     46   ChannelError error;
     47   size_t message_length;
     48 
     49   WriteToBuffer(cast_message_str_);
     50 
     51   // Receive 1 byte of the header, framer demands 3 more bytes.
     52   EXPECT_EQ(4u, framer_->BytesRequested());
     53   EXPECT_EQ(NULL, framer_->Ingest(1, &message_length, &error).get());
     54   EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, error);
     55   EXPECT_EQ(3u, framer_->BytesRequested());
     56 
     57   // Ingest remaining 3, expect that the framer has moved on to requesting the
     58   // body contents.
     59   EXPECT_EQ(NULL, framer_->Ingest(3, &message_length, &error).get());
     60   EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, error);
     61   EXPECT_EQ(
     62       cast_message_str_.size() - MessageFramer::MessageHeader::header_size(),
     63       framer_->BytesRequested());
     64 
     65   // Remainder of packet sent over the wire.
     66   scoped_ptr<CastMessage> message;
     67   message = framer_->Ingest(framer_->BytesRequested(), &message_length, &error);
     68   EXPECT_NE(static_cast<CastMessage*>(NULL), message.get());
     69   EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, error);
     70   EXPECT_EQ(message->SerializeAsString(), cast_message_.SerializeAsString());
     71   EXPECT_EQ(4u, framer_->BytesRequested());
     72   EXPECT_EQ(message->SerializeAsString().size(), message_length);
     73 }
     74 
     75 TEST_F(CastFramerTest, TestSerializeErrorMessageTooLarge) {
     76   std::string serialized;
     77   CastMessage big_message;
     78   big_message.CopyFrom(cast_message_);
     79   std::string payload;
     80   payload.append(MessageFramer::MessageHeader::max_message_size() + 1, 'x');
     81   big_message.set_payload_utf8(payload);
     82   EXPECT_FALSE(MessageFramer::Serialize(big_message, &serialized));
     83 }
     84 
     85 TEST_F(CastFramerTest, TestIngestIllegalLargeMessage) {
     86   std::string mangled_cast_message = cast_message_str_;
     87   mangled_cast_message[0] = 88;
     88   mangled_cast_message[1] = 88;
     89   mangled_cast_message[2] = 88;
     90   mangled_cast_message[3] = 88;
     91   WriteToBuffer(mangled_cast_message);
     92 
     93   size_t bytes_ingested;
     94   ChannelError error;
     95   EXPECT_EQ(4u, framer_->BytesRequested());
     96   EXPECT_EQ(NULL, framer_->Ingest(4, &bytes_ingested, &error).get());
     97   EXPECT_EQ(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, error);
     98   EXPECT_EQ(0u, framer_->BytesRequested());
     99 
    100   // Test that the parser enters a terminal error state.
    101   WriteToBuffer(cast_message_str_);
    102   EXPECT_EQ(0u, framer_->BytesRequested());
    103   EXPECT_EQ(NULL, framer_->Ingest(4, &bytes_ingested, &error).get());
    104   EXPECT_EQ(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, error);
    105   EXPECT_EQ(0u, framer_->BytesRequested());
    106 }
    107 
    108 TEST_F(CastFramerTest, TestUnparsableBodyProto) {
    109   // Message header is OK, but the body is replaced with "x"en.
    110   std::string mangled_cast_message = cast_message_str_;
    111   for (size_t i = MessageFramer::MessageHeader::header_size();
    112        i < mangled_cast_message.size();
    113        ++i) {
    114     std::fill(mangled_cast_message.begin() +
    115                   MessageFramer::MessageHeader::header_size(),
    116               mangled_cast_message.end(),
    117               'x');
    118   }
    119   WriteToBuffer(mangled_cast_message);
    120 
    121   // Send header.
    122   size_t message_length;
    123   ChannelError error;
    124   EXPECT_EQ(4u, framer_->BytesRequested());
    125   EXPECT_EQ(NULL, framer_->Ingest(4, &message_length, &error).get());
    126   EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, error);
    127   EXPECT_EQ(cast_message_str_.size() - 4, framer_->BytesRequested());
    128 
    129   // Send body, expect an error.
    130   scoped_ptr<CastMessage> message;
    131   EXPECT_EQ(NULL,
    132             framer_->Ingest(framer_->BytesRequested(), &message_length, &error)
    133                 .get());
    134   EXPECT_EQ(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, error);
    135 }
    136 }  // namespace cast_channel
    137 }  // namespace core_api
    138 }  // namespace extensions
    139