Home | History | Annotate | Download | only in native_messaging
      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