// Copyright 2011 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef IPC_IPC_TEST_SINK_H_ #define IPC_IPC_TEST_SINK_H_ #include <stddef.h> #include <stdint.h> #include <utility> #include <vector> #include "base/observer_list.h" #include "build/build_config.h" #include "ipc/ipc_channel.h" namespace IPC { class Message; // This test sink provides a "sink" for IPC messages that are sent. It allows // the caller to query messages received in various different ways. It is // designed for tests for objects that use the IPC system. // // Typical usage: // // test_sink.ClearMessages(); // do_something(); // // // We should have gotten exactly one update state message. // EXPECT_TRUE(test_sink.GetUniqeMessageMatching(ViewHostMsg_Update::ID)); // // ...and no start load messages. // EXPECT_FALSE(test_sink.GetFirstMessageMatching(ViewHostMsg_Start::ID)); // // // Now inspect a message. This assumes a message that was declared like // // this: IPC_MESSAGE_ROUTED2(ViewMsg_Foo, bool, int) // IPC::Message* msg = test_sink.GetFirstMessageMatching(ViewMsg_Foo::ID)); // ASSERT_TRUE(msg); // bool first_param; // int second_param; // ViewMsg_Foo::Read(msg, &first_param, &second_param); // // // Go on to the next phase of the test. // test_sink.ClearMessages(); // // To read a sync reply, do this: // // IPC::Message* msg = test_sink.GetUniqueMessageMatching(IPC_REPLY_ID); // ASSERT_TRUE(msg); // base::TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueTuple reply_data; // EXPECT_TRUE(ViewHostMsg_Foo::ReadReplyParam(msg, &reply_data)); // // You can also register to be notified when messages are posted to the sink. // This can be useful if you need to wait for a particular message that will // be posted asynchronously. Example usage: // // class MyListener : public IPC::Listener { // public: // MyListener(const base::RepeatingClosure& closure) // : message_received_closure_(closure) {} // virtual bool OnMessageReceived(const IPC::Message& msg) { // <do something with the message> // message_received_closure_.Run(); // return false; // to store the message in the sink, or true to drop it // } // private: // base::RepeatingClosure message_received_closure_; // }; // // base::RunLoop run_loop; // MyListener listener(run_loop.QuitClosure()); // test_sink.AddFilter(&listener); // StartSomeAsynchronousProcess(&test_sink); // run_loop.Run(); // <inspect the results> // ... // // To hook up the sink, all you need to do is call OnMessageReceived when a // message is received. class TestSink : public Channel { … }; } // namespace IPC #endif // IPC_IPC_TEST_SINK_H_