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 16 namespace remoting { 17 18 class 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 51 NativeMessagingReaderTest::NativeMessagingReaderTest() { 52 } 53 54 NativeMessagingReaderTest::~NativeMessagingReaderTest() {} 55 56 void NativeMessagingReaderTest::SetUp() { 57 ASSERT_TRUE(MakePipe(&read_file_, &write_file_)); 58 reader_.reset(new NativeMessagingReader(read_file_.Pass())); 59 } 60 61 void 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 73 void NativeMessagingReaderTest::OnMessage(scoped_ptr<base::Value> message) { 74 message_ = message.Pass(); 75 } 76 77 void NativeMessagingReaderTest::WriteMessage(std::string message) { 78 uint32 length = message.length(); 79 WriteData(reinterpret_cast<char*>(&length), 4); 80 WriteData(message.data(), length); 81 } 82 83 void NativeMessagingReaderTest::WriteData(const char* data, int length) { 84 int written = write_file_.WriteAtCurrentPos(data, length); 85 ASSERT_EQ(length, written); 86 } 87 88 TEST_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 99 TEST_F(NativeMessagingReaderTest, InvalidLength) { 100 uint32 length = 0xffffffff; 101 WriteData(reinterpret_cast<char*>(&length), 4); 102 Run(); 103 EXPECT_FALSE(message_); 104 } 105 106 TEST_F(NativeMessagingReaderTest, EmptyFile) { 107 Run(); 108 EXPECT_FALSE(message_); 109 } 110 111 TEST_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 118 TEST_F(NativeMessagingReaderTest, EmptyBody) { 119 uint32 length = 1; 120 WriteData(reinterpret_cast<char*>(&length), 4); 121 Run(); 122 EXPECT_FALSE(message_); 123 } 124 125 TEST_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 135 TEST_F(NativeMessagingReaderTest, InvalidJSON) { 136 std::string text = "{"; 137 WriteMessage(text); 138 Run(); 139 EXPECT_FALSE(message_); 140 } 141 142 TEST_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