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