Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: ipc/ipc_channel_unittest.cc

Issue 11819041: Make ipc_tests file structure a little saner and add an ipc_perftests target. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ugh Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ipc/ipc.gyp ('k') | ipc/ipc_fuzzing_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #elif defined(OS_POSIX) 9 #elif defined(OS_POSIX)
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <unistd.h> 11 #include <unistd.h>
12 #endif 12 #endif
13 13
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <string> 15 #include <string>
16 #include <utility> 16 #include <utility>
17 17
18 #include "ipc/ipc_tests.h"
19
20 #include "base/base_switches.h" 18 #include "base/base_switches.h"
21 #include "base/command_line.h" 19 #include "base/command_line.h"
22 #include "base/debug/debug_on_start_win.h" 20 #include "base/debug/debug_on_start_win.h"
23 #include "base/perftimer.h" 21 #include "base/perftimer.h"
24 #include "base/pickle.h" 22 #include "base/pickle.h"
25 #include "base/test/perf_test_suite.h" 23 #include "base/test/perf_test_suite.h"
26 #include "base/test/test_suite.h" 24 #include "base/test/test_suite.h"
27 #include "base/threading/thread.h" 25 #include "base/threading/thread.h"
28 #include "base/time.h" 26 #include "base/time.h"
29 #include "ipc/ipc_descriptors.h" 27 #include "ipc/ipc_descriptors.h"
30 #include "ipc/ipc_channel.h" 28 #include "ipc/ipc_channel.h"
31 #include "ipc/ipc_channel_proxy.h" 29 #include "ipc/ipc_channel_proxy.h"
32 #include "ipc/ipc_message_utils.h" 30 #include "ipc/ipc_message_utils.h"
33 #include "ipc/ipc_multiprocess_test.h" 31 #include "ipc/ipc_multiprocess_test.h"
34 #include "ipc/ipc_sender.h" 32 #include "ipc/ipc_sender.h"
35 #include "ipc/ipc_switches.h" 33 #include "ipc/ipc_switches.h"
34 #include "ipc/ipc_test_base.h"
36 #include "testing/multiprocess_func_list.h" 35 #include "testing/multiprocess_func_list.h"
37 36
38 // Define to enable IPC performance testing instead of the regular unit tests
39 // #define PERFORMANCE_TEST
40
41 const char kTestClientChannel[] = "T1";
42 const char kReflectorChannel[] = "T2";
43 const char kFuzzerChannel[] = "F3";
44 const char kSyncSocketChannel[] = "S4";
45
46 const size_t kLongMessageStringNumBytes = 50000; 37 const size_t kLongMessageStringNumBytes = 50000;
47 38
48 void IPCChannelTest::SetUp() { 39 class IPCChannelTest : public IPCTestBase {
49 MultiProcessTest::SetUp(); 40 };
50 41
51 // Construct a fresh IO Message loop for the duration of each test.
52 message_loop_ = new MessageLoopForIO();
53 }
54
55 void IPCChannelTest::TearDown() {
56 delete message_loop_;
57 message_loop_ = NULL;
58
59 MultiProcessTest::TearDown();
60 }
61
62 #if defined(OS_WIN)
63 base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
64 IPC::Channel *channel) {
65 // kDebugChildren support.
66 bool debug_on_start =
67 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
68
69 switch (child_type) {
70 case TEST_CLIENT:
71 return MultiProcessTest::SpawnChild("RunTestClient", debug_on_start);
72 case TEST_REFLECTOR:
73 return MultiProcessTest::SpawnChild("RunReflector", debug_on_start);
74 case FUZZER_SERVER:
75 return MultiProcessTest::SpawnChild("RunFuzzServer", debug_on_start);
76 case SYNC_SOCKET_SERVER:
77 return MultiProcessTest::SpawnChild("RunSyncSocketServer", debug_on_start);
78 default:
79 return NULL;
80 }
81 }
82 #elif defined(OS_POSIX)
83 base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
84 IPC::Channel *channel) {
85 // kDebugChildren support.
86 bool debug_on_start =
87 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
88
89 base::FileHandleMappingVector fds_to_map;
90 const int ipcfd = channel->GetClientFileDescriptor();
91 if (ipcfd > -1) {
92 fds_to_map.push_back(std::pair<int, int>(ipcfd, kPrimaryIPCChannel + 3));
93 }
94
95 base::ProcessHandle ret = base::kNullProcessHandle;
96 switch (child_type) {
97 case TEST_CLIENT:
98 ret = MultiProcessTest::SpawnChild("RunTestClient",
99 fds_to_map,
100 debug_on_start);
101 break;
102 case TEST_DESCRIPTOR_CLIENT:
103 ret = MultiProcessTest::SpawnChild("RunTestDescriptorClient",
104 fds_to_map,
105 debug_on_start);
106 break;
107 case TEST_DESCRIPTOR_CLIENT_SANDBOXED:
108 ret = MultiProcessTest::SpawnChild("RunTestDescriptorClientSandboxed",
109 fds_to_map,
110 debug_on_start);
111 break;
112 case TEST_REFLECTOR:
113 ret = MultiProcessTest::SpawnChild("RunReflector",
114 fds_to_map,
115 debug_on_start);
116 break;
117 case FUZZER_SERVER:
118 ret = MultiProcessTest::SpawnChild("RunFuzzServer",
119 fds_to_map,
120 debug_on_start);
121 break;
122 case SYNC_SOCKET_SERVER:
123 ret = MultiProcessTest::SpawnChild("RunSyncSocketServer",
124 fds_to_map,
125 debug_on_start);
126 break;
127 default:
128 return base::kNullProcessHandle;
129 break;
130 }
131 return ret;
132 }
133 #endif // defined(OS_POSIX)
134
135 #ifndef PERFORMANCE_TEST
136 TEST_F(IPCChannelTest, BasicMessageTest) { 42 TEST_F(IPCChannelTest, BasicMessageTest) {
137 int v1 = 10; 43 int v1 = 10;
138 std::string v2("foobar"); 44 std::string v2("foobar");
139 std::wstring v3(L"hello world"); 45 std::wstring v3(L"hello world");
140 46
141 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); 47 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
142 EXPECT_TRUE(m.WriteInt(v1)); 48 EXPECT_TRUE(m.WriteInt(v1));
143 EXPECT_TRUE(m.WriteString(v2)); 49 EXPECT_TRUE(m.WriteString(v2));
144 EXPECT_TRUE(m.WriteWString(v3)); 50 EXPECT_TRUE(m.WriteWString(v3));
145 51
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // setup IPC channel 327 // setup IPC channel
422 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, 328 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
423 &channel_listener); 329 &channel_listener);
424 CHECK(chan.Connect()); 330 CHECK(chan.Connect());
425 channel_listener.Init(&chan); 331 channel_listener.Init(&chan);
426 Send(&chan, "hello from child"); 332 Send(&chan, "hello from child");
427 // run message loop 333 // run message loop
428 MessageLoop::current()->Run(); 334 MessageLoop::current()->Run();
429 return 0; 335 return 0;
430 } 336 }
431
432 #endif // !PERFORMANCE_TEST
433
434 #ifdef PERFORMANCE_TEST
435
436 //-----------------------------------------------------------------------------
437 // Manually performance test
438 //
439 // This test times the roundtrip IPC message cycle. It is enabled with a
440 // special preprocessor define to enable it instead of the standard IPC
441 // unit tests. This works around some funny termination conditions in the
442 // regular unit tests.
443 //
444 // This test is not automated. To test, you will want to vary the message
445 // count and message size in TEST to get the numbers you want.
446 //
447 // FIXME(brettw): Automate this test and have it run by default.
448
449 // This channel listener just replies to all messages with the exact same
450 // message. It assumes each message has one string parameter. When the string
451 // "quit" is sent, it will exit.
452 class ChannelReflectorListener : public IPC::Listener {
453 public:
454 explicit ChannelReflectorListener(IPC::Channel *channel) :
455 channel_(channel),
456 count_messages_(0) {
457 std::cout << "Reflector up" << std::endl;
458 }
459
460 ~ChannelReflectorListener() {
461 std::cout << "Client Messages: " << count_messages_ << std::endl;
462 std::cout << "Client Latency: " << latency_messages_.InMilliseconds()
463 << std::endl;
464 }
465
466 virtual bool OnMessageReceived(const IPC::Message& message) {
467 count_messages_++;
468 PickleIterator iter(message);
469 int64 time_internal;
470 EXPECT_TRUE(iter.ReadInt64(&time_internal));
471 int msgid;
472 EXPECT_TRUE(iter.ReadInt(&msgid));
473 std::string payload;
474 EXPECT_TRUE(iter.ReadString(&payload));
475 // TODO(vtl): Should we use |HighResNow()| instead of |Now()|?
476 latency_messages_ += base::TimeTicks::Now() -
477 base::TimeTicks::FromInternalValue(time_internal);
478
479 // cout << "reflector msg received: " << msgid << endl;
480 if (payload == "quit")
481 MessageLoop::current()->Quit();
482
483 IPC::Message* msg = new IPC::Message(0,
484 2,
485 IPC::Message::PRIORITY_NORMAL);
486 msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
487 msg->WriteInt(msgid);
488 msg->WriteString(payload);
489 channel_->Send(msg);
490 return true;
491 }
492
493 private:
494 IPC::Channel *channel_;
495 int count_messages_;
496 base::TimeDelta latency_messages_;
497 };
498
499 class ChannelPerfListener : public IPC::Listener {
500 public:
501 ChannelPerfListener(IPC::Channel* channel, int msg_count, int msg_size) :
502 count_down_(msg_count),
503 channel_(channel),
504 count_messages_(0) {
505 payload_.resize(msg_size);
506 for (int i = 0; i < static_cast<int>(payload_.size()); i++)
507 payload_[i] = 'a';
508 std::cout << "perflistener up" << std::endl;
509 }
510
511 ~ChannelPerfListener() {
512 std::cout << "Server Messages: " << count_messages_ << std::endl;
513 std::cout << "Server Latency: " << latency_messages_.InMilliseconds()
514 << std::endl;
515 }
516
517 virtual bool OnMessageReceived(const IPC::Message& message) {
518 count_messages_++;
519 // Decode the string so this gets counted in the total time.
520 PickleIterator iter(message);
521 int64 time_internal;
522 EXPECT_TRUE(iter.ReadInt64(&time_internal));
523 int msgid;
524 EXPECT_TRUE(iter.ReadInt(&msgid));
525 std::string cur;
526 EXPECT_TRUE(iter.ReadString(&cur));
527 latency_messages_ += base::TimeTicks::Now() -
528 base::TimeTicks::FromInternalValue(time_internal);
529
530 count_down_--;
531 if (count_down_ == 0) {
532 IPC::Message* msg = new IPC::Message(0,
533 2,
534 IPC::Message::PRIORITY_NORMAL);
535 msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
536 msg->WriteInt(count_down_);
537 msg->WriteString("quit");
538 channel_->Send(msg);
539
540 MessageLoop::current()->QuitWhenIdle();
541 return true;
542 }
543
544 IPC::Message* msg = new IPC::Message(0,
545 2,
546 IPC::Message::PRIORITY_NORMAL);
547 msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
548 msg->WriteInt(count_down_);
549 msg->WriteString(payload_);
550 channel_->Send(msg);
551 return true;
552 }
553
554 private:
555 int count_down_;
556 std::string payload_;
557 IPC::Channel *channel_;
558 int count_messages_;
559 base::TimeDelta latency_messages_;
560 };
561
562 TEST_F(IPCChannelTest, Performance) {
563 // setup IPC channel
564 IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_SERVER, NULL);
565 ChannelPerfListener perf_listener(&chan, 10000, 100000);
566 chan.set_listener(&perf_listener);
567 ASSERT_TRUE(chan.Connect());
568
569 base::ProcessHandle process_handle = SpawnChild(TEST_REFLECTOR, &chan);
570 ASSERT_TRUE(process_handle);
571
572 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
573
574 PerfTimeLogger logger("IPC_Perf");
575
576 // this initial message will kick-start the ping-pong of messages
577 IPC::Message* message = new IPC::Message(0,
578 2,
579 IPC::Message::PRIORITY_NORMAL);
580 message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
581 message->WriteInt(-1);
582 message->WriteString("Hello");
583 chan.Send(message);
584
585 // run message loop
586 MessageLoop::current()->Run();
587
588 // Clean up child process.
589 EXPECT_TRUE(base::WaitForSingleProcess(
590 process_handle, base::TimeDelta::FromSeconds(5)));
591 base::CloseProcessHandle(process_handle);
592 }
593
594 // This message loop bounces all messages back to the sender
595 MULTIPROCESS_IPC_TEST_MAIN(RunReflector) {
596 MessageLoopForIO main_message_loop;
597 IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_CLIENT, NULL);
598 ChannelReflectorListener channel_reflector_listener(&chan);
599 chan.set_listener(&channel_reflector_listener);
600 CHECK(chan.Connect());
601
602 MessageLoop::current()->Run();
603 return 0;
604 }
605
606 #endif // PERFORMANCE_TEST
607
608 int main(int argc, char** argv) {
609 #ifdef PERFORMANCE_TEST
610 int retval = base::PerfTestSuite(argc, argv).Run();
611 #else
612 int retval = base::TestSuite(argc, argv).Run();
613 #endif
614 return retval;
615 }
OLDNEW
« no previous file with comments | « ipc/ipc.gyp ('k') | ipc/ipc_fuzzing_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698