blob: c11fb70d43f4816d45a7aa5b4b0dccfb86a2c24b [file] [log] [blame]
[email protected]b7243c42010-07-23 05:23:131// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]645aaa52009-02-07 01:03:055#include "build/build_config.h"
6
[email protected]d4651ff2008-12-02 16:51:587#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:298#include <windows.h>
[email protected]43cf8152009-02-07 00:57:459#elif defined(OS_POSIX)
10#include <sys/types.h>
[email protected]43cf8152009-02-07 00:57:4511#include <unistd.h>
[email protected]d4651ff2008-12-02 16:51:5812#endif
[email protected]43cf8152009-02-07 00:57:4513
initial.commit09911bf2008-07-26 23:55:2914#include <stdio.h>
initial.commit09911bf2008-07-26 23:55:2915#include <string>
[email protected]b7243c42010-07-23 05:23:1316#include <utility>
initial.commit09911bf2008-07-26 23:55:2917
[email protected]946d1b22009-07-22 23:57:2118#include "ipc/ipc_tests.h"
initial.commit09911bf2008-07-26 23:55:2919
[email protected]ae6454712008-08-01 03:06:2520#include "base/at_exit.h"
initial.commit09911bf2008-07-26 23:55:2921#include "base/base_switches.h"
22#include "base/command_line.h"
23#include "base/debug_on_start.h"
24#include "base/perftimer.h"
[email protected]fb895c62009-10-09 18:20:3025#include "base/test/perf_test_suite.h"
26#include "base/test/test_suite.h"
initial.commit09911bf2008-07-26 23:55:2927#include "base/thread.h"
[email protected]946d1b22009-07-22 23:57:2128#include "ipc/ipc_descriptors.h"
29#include "ipc/ipc_channel.h"
30#include "ipc/ipc_channel_proxy.h"
31#include "ipc/ipc_message_utils.h"
32#include "ipc/ipc_switches.h"
[email protected]95cb7fb92008-12-09 22:00:4733#include "testing/multiprocess_func_list.h"
initial.commit09911bf2008-07-26 23:55:2934
35// Define to enable IPC performance testing instead of the regular unit tests
36// #define PERFORMANCE_TEST
37
[email protected]9a3a293b2009-06-04 22:28:1638const char kTestClientChannel[] = "T1";
39const char kReflectorChannel[] = "T2";
40const char kFuzzerChannel[] = "F3";
[email protected]0840cc72009-11-24 16:14:5341const char kSyncSocketChannel[] = "S4";
initial.commit09911bf2008-07-26 23:55:2942
[email protected]c2f10ed2009-02-10 00:52:5743const size_t kLongMessageStringNumBytes = 50000;
44
initial.commit09911bf2008-07-26 23:55:2945#ifndef PERFORMANCE_TEST
46
[email protected]95cb7fb92008-12-09 22:00:4747void IPCChannelTest::SetUp() {
48 MultiProcessTest::SetUp();
49
50 // Construct a fresh IO Message loop for the duration of each test.
51 message_loop_ = new MessageLoopForIO();
52}
53
54void IPCChannelTest::TearDown() {
55 delete message_loop_;
56 message_loop_ = NULL;
57
58 MultiProcessTest::TearDown();
59}
60
[email protected]df3c1ca12008-12-19 21:37:0161#if defined(OS_WIN)
62base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
63 IPC::Channel *channel) {
[email protected]95cb7fb92008-12-09 22:00:4764 // kDebugChildren support.
[email protected]bb975362009-01-21 01:00:2265 bool debug_on_start =
66 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
[email protected]95cb7fb92008-12-09 22:00:4767
68 switch (child_type) {
69 case TEST_CLIENT:
70 return MultiProcessTest::SpawnChild(L"RunTestClient", debug_on_start);
71 break;
72 case TEST_REFLECTOR:
73 return MultiProcessTest::SpawnChild(L"RunReflector", debug_on_start);
74 break;
75 case FUZZER_SERVER:
76 return MultiProcessTest::SpawnChild(L"RunFuzzServer", debug_on_start);
77 break;
[email protected]0840cc72009-11-24 16:14:5378 case SYNC_SOCKET_SERVER:
79 return MultiProcessTest::SpawnChild(L"RunSyncSocketServer", debug_on_start);
80 break;
[email protected]95cb7fb92008-12-09 22:00:4781 default:
82 return NULL;
83 break;
84 }
85}
[email protected]df3c1ca12008-12-19 21:37:0186#elif defined(OS_POSIX)
87base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
88 IPC::Channel *channel) {
89 // kDebugChildren support.
[email protected]bb975362009-01-21 01:00:2290 bool debug_on_start =
91 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
[email protected]df3c1ca12008-12-19 21:37:0192
93 base::file_handle_mapping_vector fds_to_map;
[email protected]cc8f1462009-06-12 17:36:5594 const int ipcfd = channel->GetClientFileDescriptor();
95 if (ipcfd > -1) {
[email protected]b7243c42010-07-23 05:23:1396 fds_to_map.push_back(std::pair<int, int>(ipcfd, kPrimaryIPCChannel + 3));
[email protected]df3c1ca12008-12-19 21:37:0197 }
98
99 base::ProcessHandle ret = NULL;
100 switch (child_type) {
101 case TEST_CLIENT:
102 ret = MultiProcessTest::SpawnChild(L"RunTestClient",
103 fds_to_map,
104 debug_on_start);
[email protected]df3c1ca12008-12-19 21:37:01105 break;
[email protected]526776c2009-02-07 00:39:26106 case TEST_DESCRIPTOR_CLIENT:
107 ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClient",
108 fds_to_map,
109 debug_on_start);
[email protected]526776c2009-02-07 00:39:26110 break;
[email protected]e8351b7e2009-02-10 22:25:39111 case TEST_DESCRIPTOR_CLIENT_SANDBOXED:
112 ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClientSandboxed",
113 fds_to_map,
114 debug_on_start);
[email protected]e8351b7e2009-02-10 22:25:39115 break;
[email protected]df3c1ca12008-12-19 21:37:01116 case TEST_REFLECTOR:
117 ret = MultiProcessTest::SpawnChild(L"RunReflector",
118 fds_to_map,
119 debug_on_start);
[email protected]df3c1ca12008-12-19 21:37:01120 break;
121 case FUZZER_SERVER:
122 ret = MultiProcessTest::SpawnChild(L"RunFuzzServer",
123 fds_to_map,
124 debug_on_start);
[email protected]df3c1ca12008-12-19 21:37:01125 break;
[email protected]0840cc72009-11-24 16:14:53126 case SYNC_SOCKET_SERVER:
127 ret = MultiProcessTest::SpawnChild(L"RunSyncSocketServer",
128 fds_to_map,
129 debug_on_start);
130 break;
[email protected]df3c1ca12008-12-19 21:37:01131 default:
132 return NULL;
133 break;
134 }
135 return ret;
136}
137#endif // defined(OS_POSIX)
[email protected]95cb7fb92008-12-09 22:00:47138
139TEST_F(IPCChannelTest, BasicMessageTest) {
initial.commit09911bf2008-07-26 23:55:29140 int v1 = 10;
141 std::string v2("foobar");
142 std::wstring v3(L"hello world");
143
144 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
145 EXPECT_TRUE(m.WriteInt(v1));
146 EXPECT_TRUE(m.WriteString(v2));
147 EXPECT_TRUE(m.WriteWString(v3));
148
149 void* iter = NULL;
150
151 int vi;
152 std::string vs;
153 std::wstring vw;
154
155 EXPECT_TRUE(m.ReadInt(&iter, &vi));
156 EXPECT_EQ(v1, vi);
157
158 EXPECT_TRUE(m.ReadString(&iter, &vs));
159 EXPECT_EQ(v2, vs);
160
161 EXPECT_TRUE(m.ReadWString(&iter, &vw));
162 EXPECT_EQ(v3, vw);
163
164 // should fail
165 EXPECT_FALSE(m.ReadInt(&iter, &vi));
166 EXPECT_FALSE(m.ReadString(&iter, &vs));
167 EXPECT_FALSE(m.ReadWString(&iter, &vw));
168}
169
170static void Send(IPC::Message::Sender* sender, const char* text) {
171 static int message_index = 0;
172
173 IPC::Message* message = new IPC::Message(0,
174 2,
175 IPC::Message::PRIORITY_NORMAL);
176 message->WriteInt(message_index++);
177 message->WriteString(std::string(text));
178
[email protected]3d1b6662009-01-29 17:03:11179 // Make sure we can handle large messages.
[email protected]c2f10ed2009-02-10 00:52:57180 char junk[kLongMessageStringNumBytes];
[email protected]3d1b6662009-01-29 17:03:11181 memset(junk, 'a', sizeof(junk)-1);
initial.commit09911bf2008-07-26 23:55:29182 junk[sizeof(junk)-1] = 0;
183 message->WriteString(std::string(junk));
184
185 // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text);
186 sender->Send(message);
187}
188
189class MyChannelListener : public IPC::Channel::Listener {
190 public:
191 virtual void OnMessageReceived(const IPC::Message& message) {
192 IPC::MessageIterator iter(message);
193
[email protected]d4651ff2008-12-02 16:51:58194 iter.NextInt();
initial.commit09911bf2008-07-26 23:55:29195 const std::string data = iter.NextString();
[email protected]c2f10ed2009-02-10 00:52:57196 const std::string big_string = iter.NextString();
197 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
198
199
initial.commit09911bf2008-07-26 23:55:29200 if (--messages_left_ == 0) {
201 MessageLoop::current()->Quit();
202 } else {
203 Send(sender_, "Foo");
204 }
205 }
206
[email protected]b6be5882008-11-07 21:53:03207 virtual void OnChannelError() {
208 // There is a race when closing the channel so the last message may be lost.
209 EXPECT_LE(messages_left_, 1);
210 MessageLoop::current()->Quit();
211 }
212
initial.commit09911bf2008-07-26 23:55:29213 void Init(IPC::Message::Sender* s) {
214 sender_ = s;
215 messages_left_ = 50;
216 }
217
218 private:
219 IPC::Message::Sender* sender_;
220 int messages_left_;
221};
initial.commit09911bf2008-07-26 23:55:29222
[email protected]95cb7fb92008-12-09 22:00:47223TEST_F(IPCChannelTest, ChannelTest) {
[email protected]c2f10ed2009-02-10 00:52:57224 MyChannelListener channel_listener;
[email protected]3d1b6662009-01-29 17:03:11225 // Setup IPC channel.
initial.commit09911bf2008-07-26 23:55:29226 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
227 &channel_listener);
228 chan.Connect();
229
230 channel_listener.Init(&chan);
231
[email protected]df3c1ca12008-12-19 21:37:01232 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan);
initial.commit09911bf2008-07-26 23:55:29233 ASSERT_TRUE(process_handle);
234
235 Send(&chan, "hello from parent");
236
[email protected]3d1b6662009-01-29 17:03:11237 // Run message loop.
initial.commit09911bf2008-07-26 23:55:29238 MessageLoop::current()->Run();
239
[email protected]3d1b6662009-01-29 17:03:11240 // Close Channel so client gets its OnChannelError() callback fired.
241 chan.Close();
242
243 // Cleanup child process.
[email protected]95cb7fb92008-12-09 22:00:47244 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
[email protected]cd4fd152009-02-09 19:28:41245 base::CloseProcessHandle(process_handle);
initial.commit09911bf2008-07-26 23:55:29246}
247
[email protected]95cb7fb92008-12-09 22:00:47248TEST_F(IPCChannelTest, ChannelProxyTest) {
[email protected]c2f10ed2009-02-10 00:52:57249 MyChannelListener channel_listener;
250
initial.commit09911bf2008-07-26 23:55:29251 // The thread needs to out-live the ChannelProxy.
[email protected]ab820df2008-08-26 05:55:10252 base::Thread thread("ChannelProxyTestServer");
253 base::Thread::Options options;
254 options.message_loop_type = MessageLoop::TYPE_IO;
255 thread.StartWithOptions(options);
initial.commit09911bf2008-07-26 23:55:29256 {
257 // setup IPC channel proxy
258 IPC::ChannelProxy chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
259 &channel_listener, NULL, thread.message_loop());
260
261 channel_listener.Init(&chan);
262
[email protected]e74488c2008-12-22 22:43:41263#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:22264 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, NULL);
[email protected]e74488c2008-12-22 22:43:41265#elif defined(OS_POSIX)
[email protected]bb975362009-01-21 01:00:22266 bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch(
267 switches::kDebugChildren);
[email protected]e74488c2008-12-22 22:43:41268 base::file_handle_mapping_vector fds_to_map;
[email protected]cc8f1462009-06-12 17:36:55269 const int ipcfd = chan.GetClientFileDescriptor();
270 if (ipcfd > -1) {
[email protected]b7243c42010-07-23 05:23:13271 fds_to_map.push_back(std::pair<int, int>(ipcfd, kPrimaryIPCChannel + 3));
[email protected]e74488c2008-12-22 22:43:41272 }
273
[email protected]df3c1ca12008-12-19 21:37:01274 base::ProcessHandle process_handle = MultiProcessTest::SpawnChild(
275 L"RunTestClient",
[email protected]e74488c2008-12-22 22:43:41276 fds_to_map,
[email protected]df3c1ca12008-12-19 21:37:01277 debug_on_start);
[email protected]1db97ce72009-08-21 21:53:54278#endif // defined(OS_POSIX)
[email protected]e74488c2008-12-22 22:43:41279
initial.commit09911bf2008-07-26 23:55:29280 ASSERT_TRUE(process_handle);
281
282 Send(&chan, "hello from parent");
283
284 // run message loop
285 MessageLoop::current()->Run();
286
287 // cleanup child process
[email protected]df3c1ca12008-12-19 21:37:01288 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
[email protected]cd4fd152009-02-09 19:28:41289 base::CloseProcessHandle(process_handle);
initial.commit09911bf2008-07-26 23:55:29290 }
291 thread.Stop();
292}
293
[email protected]052fd452009-09-23 17:56:25294class ChannelListenerWithOnConnectedSend : public IPC::Channel::Listener {
295 public:
296 virtual void OnChannelConnected(int32 peer_pid) {
297 SendNextMessage();
298 }
299
300 virtual void OnMessageReceived(const IPC::Message& message) {
301 IPC::MessageIterator iter(message);
302
303 iter.NextInt();
304 const std::string data = iter.NextString();
305 const std::string big_string = iter.NextString();
306 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
307 SendNextMessage();
308 }
309
310 virtual void OnChannelError() {
311 // There is a race when closing the channel so the last message may be lost.
312 EXPECT_LE(messages_left_, 1);
313 MessageLoop::current()->Quit();
314 }
315
316 void Init(IPC::Message::Sender* s) {
317 sender_ = s;
318 messages_left_ = 50;
319 }
320
321 private:
322 void SendNextMessage() {
323 if (--messages_left_ == 0) {
324 MessageLoop::current()->Quit();
325 } else {
326 Send(sender_, "Foo");
327 }
328 }
329
330 IPC::Message::Sender* sender_;
331 int messages_left_;
332};
333
334TEST_F(IPCChannelTest, SendMessageInChannelConnected) {
335 // This tests the case of a listener sending back an event in it's
336 // OnChannelConnected handler.
337
338 ChannelListenerWithOnConnectedSend channel_listener;
339 // Setup IPC channel.
340 IPC::Channel channel(kTestClientChannel, IPC::Channel::MODE_SERVER,
341 &channel_listener);
342 channel_listener.Init(&channel);
343 channel.Connect();
344
345 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &channel);
346 ASSERT_TRUE(process_handle);
347
348 Send(&channel, "hello from parent");
349
350 // Run message loop.
351 MessageLoop::current()->Run();
352
353 // Close Channel so client gets its OnChannelError() callback fired.
354 channel.Close();
355
356 // Cleanup child process.
357 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
358 base::CloseProcessHandle(process_handle);
359}
360
[email protected]95cb7fb92008-12-09 22:00:47361MULTIPROCESS_TEST_MAIN(RunTestClient) {
362 MessageLoopForIO main_message_loop;
[email protected]c2f10ed2009-02-10 00:52:57363 MyChannelListener channel_listener;
[email protected]95cb7fb92008-12-09 22:00:47364
initial.commit09911bf2008-07-26 23:55:29365 // setup IPC channel
366 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
367 &channel_listener);
368 chan.Connect();
369 channel_listener.Init(&chan);
370 Send(&chan, "hello from child");
371 // run message loop
372 MessageLoop::current()->Run();
[email protected]95cb7fb92008-12-09 22:00:47373 // return true;
374 return NULL;
initial.commit09911bf2008-07-26 23:55:29375}
[email protected]526776c2009-02-07 00:39:26376
initial.commit09911bf2008-07-26 23:55:29377#endif // !PERFORMANCE_TEST
378
379#ifdef PERFORMANCE_TEST
380
381//-----------------------------------------------------------------------------
382// Manually performance test
383//
384// This test times the roundtrip IPC message cycle. It is enabled with a
385// special preprocessor define to enable it instead of the standard IPC
386// unit tests. This works around some funny termination conditions in the
387// regular unit tests.
388//
389// This test is not automated. To test, you will want to vary the message
390// count and message size in TEST to get the numbers you want.
391//
392// FIXME(brettw): Automate this test and have it run by default.
393
394// This channel listener just replies to all messages with the exact same
395// message. It assumes each message has one string parameter. When the string
396// "quit" is sent, it will exit.
397class ChannelReflectorListener : public IPC::Channel::Listener {
398 public:
[email protected]95cb7fb92008-12-09 22:00:47399 explicit ChannelReflectorListener(IPC::Channel *channel) :
initial.commit09911bf2008-07-26 23:55:29400 channel_(channel),
401 count_messages_(0),
402 latency_messages_(0) {
403 std::cout << "Reflector up" << std::endl;
404 }
405
406 ~ChannelReflectorListener() {
407 std::cout << "Client Messages: " << count_messages_ << std::endl;
408 std::cout << "Client Latency: " << latency_messages_ << std::endl;
409 }
410
411 virtual void OnMessageReceived(const IPC::Message& message) {
412 count_messages_++;
413 IPC::MessageIterator iter(message);
414 int time = iter.NextInt();
415 int msgid = iter.NextInt();
416 std::string payload = iter.NextString();
417 latency_messages_ += GetTickCount() - time;
418
419 // cout << "reflector msg received: " << msgid << endl;
420 if (payload == "quit")
421 MessageLoop::current()->Quit();
422
423 IPC::Message* msg = new IPC::Message(0,
424 2,
425 IPC::Message::PRIORITY_NORMAL);
426 msg->WriteInt(GetTickCount());
427 msg->WriteInt(msgid);
428 msg->WriteString(payload);
429 channel_->Send(msg);
430 }
431 private:
432 IPC::Channel *channel_;
433 int count_messages_;
434 int latency_messages_;
435};
436
437class ChannelPerfListener : public IPC::Channel::Listener {
438 public:
439 ChannelPerfListener(IPC::Channel* channel, int msg_count, int msg_size) :
440 count_down_(msg_count),
441 channel_(channel),
442 count_messages_(0),
443 latency_messages_(0) {
444 payload_.resize(msg_size);
445 for (int i = 0; i < static_cast<int>(payload_.size()); i++)
446 payload_[i] = 'a';
447 std::cout << "perflistener up" << std::endl;
448 }
449
450 ~ChannelPerfListener() {
451 std::cout << "Server Messages: " << count_messages_ << std::endl;
452 std::cout << "Server Latency: " << latency_messages_ << std::endl;
453 }
454
455 virtual void OnMessageReceived(const IPC::Message& message) {
456 count_messages_++;
457 // decode the string so this gets counted in the total time
458 IPC::MessageIterator iter(message);
459 int time = iter.NextInt();
460 int msgid = iter.NextInt();
461 std::string cur = iter.NextString();
462 latency_messages_ += GetTickCount() - time;
463
464 // cout << "perflistener got message" << endl;
465
466 count_down_--;
467 if (count_down_ == 0) {
468 IPC::Message* msg = new IPC::Message(0,
469 2,
470 IPC::Message::PRIORITY_NORMAL);
471 msg->WriteInt(GetTickCount());
472 msg->WriteInt(count_down_);
473 msg->WriteString("quit");
474 channel_->Send(msg);
475 SetTimer(NULL, 1, 250, (TIMERPROC) PostQuitMessage);
476 return;
477 }
478
479 IPC::Message* msg = new IPC::Message(0,
480 2,
481 IPC::Message::PRIORITY_NORMAL);
482 msg->WriteInt(GetTickCount());
483 msg->WriteInt(count_down_);
484 msg->WriteString(payload_);
485 channel_->Send(msg);
486 }
487
488 private:
489 int count_down_;
490 std::string payload_;
491 IPC::Channel *channel_;
492 int count_messages_;
493 int latency_messages_;
494};
495
[email protected]95cb7fb92008-12-09 22:00:47496TEST_F(IPCChannelTest, Performance) {
initial.commit09911bf2008-07-26 23:55:29497 // setup IPC channel
498 IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_SERVER, NULL);
499 ChannelPerfListener perf_listener(&chan, 10000, 100000);
500 chan.set_listener(&perf_listener);
501 chan.Connect();
502
[email protected]df3c1ca12008-12-19 21:37:01503 HANDLE process = SpawnChild(TEST_REFLECTOR, &chan);
initial.commit09911bf2008-07-26 23:55:29504 ASSERT_TRUE(process);
505
[email protected]ec7690f2009-04-28 00:11:27506 PlatformThread::Sleep(1000);
initial.commit09911bf2008-07-26 23:55:29507
508 PerfTimeLogger logger("IPC_Perf");
509
510 // this initial message will kick-start the ping-pong of messages
511 IPC::Message* message = new IPC::Message(0,
512 2,
513 IPC::Message::PRIORITY_NORMAL);
514 message->WriteInt(GetTickCount());
515 message->WriteInt(-1);
516 message->WriteString("Hello");
517 chan.Send(message);
518
519 // run message loop
520 MessageLoop::current()->Run();
521
522 // cleanup child process
523 WaitForSingleObject(process, 5000);
524 CloseHandle(process);
525}
526
527// This message loop bounces all messages back to the sender
[email protected]95cb7fb92008-12-09 22:00:47528MULTIPROCESS_TEST_MAIN(RunReflector) {
529 MessageLoopForIO main_message_loop;
initial.commit09911bf2008-07-26 23:55:29530 IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_CLIENT, NULL);
531 ChannelReflectorListener channel_reflector_listener(&chan);
532 chan.set_listener(&channel_reflector_listener);
533 chan.Connect();
534
535 MessageLoop::current()->Run();
536 return true;
537}
538
539#endif // PERFORMANCE_TEST
540
initial.commit09911bf2008-07-26 23:55:29541int main(int argc, char** argv) {
[email protected]95cb7fb92008-12-09 22:00:47542#ifdef PERFORMANCE_TEST
[email protected]302831b2009-01-13 22:35:10543 int retval = PerfTestSuite(argc, argv).Run();
544#else
545 int retval = TestSuite(argc, argv).Run();
initial.commit09911bf2008-07-26 23:55:29546#endif
[email protected]95cb7fb92008-12-09 22:00:47547 return retval;
initial.commit09911bf2008-07-26 23:55:29548}