1// Copyright 2013 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 "remoting/host/native_messaging/native_messaging_reader.h" 6 7#include "base/basictypes.h" 8#include "base/bind.h" 9#include "base/memory/scoped_ptr.h" 10#include "base/message_loop/message_loop.h" 11#include "base/run_loop.h" 12#include "base/values.h" 13#include "remoting/host/setup/test_util.h" 14#include "testing/gtest/include/gtest/gtest.h" 15 16namespace remoting { 17 18class NativeMessagingReaderTest : public testing::Test { 19 public: 20 NativeMessagingReaderTest(); 21 virtual ~NativeMessagingReaderTest(); 22 23 virtual void SetUp() OVERRIDE; 24 25 // Starts the reader and runs the MessageLoop to completion. 26 void Run(); 27 28 // MessageCallback passed to the Reader. Stores |message| so it can be 29 // verified by tests. 30 void OnMessage(scoped_ptr<base::Value> message); 31 32 // Writes a message (header+body) to the write-end of the pipe. 33 void WriteMessage(std::string message); 34 35 // Writes some data to the write-end of the pipe. 36 void WriteData(const char* data, int length); 37 38 protected: 39 scoped_ptr<NativeMessagingReader> reader_; 40 base::File read_file_; 41 base::File write_file_; 42 scoped_ptr<base::Value> message_; 43 44 private: 45 // MessageLoop declared here, since the NativeMessageReader ctor requires a 46 // MessageLoop to have been created. 47 base::MessageLoopForIO message_loop_; 48 base::RunLoop run_loop_; 49}; 50 51NativeMessagingReaderTest::NativeMessagingReaderTest() { 52} 53 54NativeMessagingReaderTest::~NativeMessagingReaderTest() {} 55 56void NativeMessagingReaderTest::SetUp() { 57 ASSERT_TRUE(MakePipe(&read_file_, &write_file_)); 58 reader_.reset(new NativeMessagingReader(read_file_.Pass())); 59} 60 61void NativeMessagingReaderTest::Run() { 62 // Close the write-end, so the reader doesn't block waiting for more data. 63 write_file_.Close(); 64 65 // base::Unretained is safe since no further tasks can run after 66 // RunLoop::Run() returns. 67 reader_->Start( 68 base::Bind(&NativeMessagingReaderTest::OnMessage, base::Unretained(this)), 69 run_loop_.QuitClosure()); 70 run_loop_.Run(); 71} 72 73void NativeMessagingReaderTest::OnMessage(scoped_ptr<base::Value> message) { 74 message_ = message.Pass(); 75} 76 77void NativeMessagingReaderTest::WriteMessage(std::string message) { 78 uint32 length = message.length(); 79 WriteData(reinterpret_cast<char*>(&length), 4); 80 WriteData(message.data(), length); 81} 82 83void NativeMessagingReaderTest::WriteData(const char* data, int length) { 84 int written = write_file_.WriteAtCurrentPos(data, length); 85 ASSERT_EQ(length, written); 86} 87 88TEST_F(NativeMessagingReaderTest, GoodMessage) { 89 WriteMessage("{\"foo\": 42}"); 90 Run(); 91 EXPECT_TRUE(message_); 92 base::DictionaryValue* message_dict; 93 EXPECT_TRUE(message_->GetAsDictionary(&message_dict)); 94 int result; 95 EXPECT_TRUE(message_dict->GetInteger("foo", &result)); 96 EXPECT_EQ(42, result); 97} 98 99TEST_F(NativeMessagingReaderTest, InvalidLength) { 100 uint32 length = 0xffffffff; 101 WriteData(reinterpret_cast<char*>(&length), 4); 102 Run(); 103 EXPECT_FALSE(message_); 104} 105 106TEST_F(NativeMessagingReaderTest, EmptyFile) { 107 Run(); 108 EXPECT_FALSE(message_); 109} 110 111TEST_F(NativeMessagingReaderTest, ShortHeader) { 112 // Write only 3 bytes - the message length header is supposed to be 4 bytes. 113 WriteData("xxx", 3); 114 Run(); 115 EXPECT_FALSE(message_); 116} 117 118TEST_F(NativeMessagingReaderTest, EmptyBody) { 119 uint32 length = 1; 120 WriteData(reinterpret_cast<char*>(&length), 4); 121 Run(); 122 EXPECT_FALSE(message_); 123} 124 125TEST_F(NativeMessagingReaderTest, ShortBody) { 126 uint32 length = 2; 127 WriteData(reinterpret_cast<char*>(&length), 4); 128 129 // Only write 1 byte, where the header indicates there should be 2 bytes. 130 WriteData("x", 1); 131 Run(); 132 EXPECT_FALSE(message_); 133} 134 135TEST_F(NativeMessagingReaderTest, InvalidJSON) { 136 std::string text = "{"; 137 WriteMessage(text); 138 Run(); 139 EXPECT_FALSE(message_); 140} 141 142TEST_F(NativeMessagingReaderTest, SecondMessage) { 143 WriteMessage("{}"); 144 WriteMessage("{\"foo\": 42}"); 145 Run(); 146 EXPECT_TRUE(message_); 147 base::DictionaryValue* message_dict; 148 EXPECT_TRUE(message_->GetAsDictionary(&message_dict)); 149 int result; 150 EXPECT_TRUE(message_dict->GetInteger("foo", &result)); 151 EXPECT_EQ(42, result); 152} 153 154} // namespace remoting 155