No bug: Test RPC round-trip times and warn before sleep()ing. no r=, test only
authorChris Jones <jones.chris.g@gmail.com>
Thu, 04 Feb 2010 21:40:42 -0600
changeset 46641 240e383440c40844d335ce2229f18125b1f961f3
parent 46640 367b795dfbcff37d738e0f4b66f43a2f00de7751
child 46642 a77f5a6cce34dece7c0b90275001fa35b80465de
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone1.9.3a1pre
No bug: Test RPC round-trip times and warn before sleep()ing. no r=, test only
ipc/ipdl/test/cxx/PTestLatency.ipdl
ipc/ipdl/test/cxx/TestLatency.cpp
ipc/ipdl/test/cxx/TestLatency.h
ipc/ipdl/test/cxx/TestSyncWakeup.cpp
--- a/ipc/ipdl/test/cxx/PTestLatency.ipdl
+++ b/ipc/ipdl/test/cxx/PTestLatency.ipdl
@@ -1,19 +1,20 @@
 
 namespace mozilla {
 namespace _ipdltest {
 
 
-protocol PTestLatency {
+rpc protocol PTestLatency {
 
 child:
     __delete__();
     Ping();
     Ping5();
+    rpc Rpc();
 
 parent:
     Pong();
     Pong5();
 
 state START:
     // if the timing resolution is too low, abort the test
     send __delete__;
@@ -26,25 +27,29 @@ state PING:
     send Ping5 goto PING4;
 
 state PONG:
     recv Pong goto PING;
 
     // Trial 2: "overlapped" ping/pong latency
 state PING5:
     send Ping5 goto PING4;
-    send __delete__;
+    call Rpc goto RPC;
 
 state PING4: send Ping5 goto PING3;
 state PING3: send Ping5 goto PING2;
 state PING2: send Ping5 goto PING1;
 state PING1: send Ping5 goto PONG1;
 
 state PONG1: recv Pong5 goto PONG2;
 state PONG2: recv Pong5 goto PONG3;
 state PONG3: recv Pong5 goto PONG4;
 state PONG4: recv Pong5 goto PONG5;
 state PONG5: recv Pong5 goto PING5;
+
+state RPC:
+    call Rpc goto RPC;
+    send __delete__;
 };
 
 
 } // namespace mozilla
 } // namespace _ipdltest
--- a/ipc/ipdl/test/cxx/TestLatency.cpp
+++ b/ipc/ipdl/test/cxx/TestLatency.cpp
@@ -11,37 +11,42 @@ namespace _ipdltest {
 
 //-----------------------------------------------------------------------------
 // parent
 
 TestLatencyParent::TestLatencyParent() :
     mStart(),
     mPPTimeTotal(),
     mPP5TimeTotal(),
+    mRpcTimeTotal(),
     mPPTrialsToGo(NR_TRIALS),
     mPP5TrialsToGo(NR_TRIALS),
     mPongsToGo(0)
 {
     MOZ_COUNT_CTOR(TestLatencyParent);
 }
 
 TestLatencyParent::~TestLatencyParent()
 {
     MOZ_COUNT_DTOR(TestLatencyParent);
 }
 
 void
 TestLatencyParent::Main()
 {
-    if (TimeDuration::Resolution().ToSeconds() > kTimingResolutionCutoff) {
+    TimeDuration resolution = TimeDuration::Resolution();
+    if (resolution.ToSeconds() > kTimingResolutionCutoff) {
         puts("  (skipping TestLatency, timing resolution is too poor)");
         Close();
         return;
     }
 
+    printf("  timing resolution: %g seconds\n",
+           resolution.ToSecondsSigDigits());
+
     if (mozilla::ipc::LoggingEnabled())
         NS_RUNTIMEABORT("you really don't want to log all IPC messages during this test, trust me");
 
     PingPongTrial();
 }
 
 void
 TestLatencyParent::PingPongTrial()
@@ -71,17 +76,17 @@ TestLatencyParent::Exit()
 }
 
 bool
 TestLatencyParent::RecvPong()
 {
     TimeDuration thisTrial = (TimeStamp::Now() - mStart);
     mPPTimeTotal += thisTrial;
 
-    if (0 == ((mPPTrialsToGo % 1000)))
+    if (0 == (mPPTrialsToGo % 1000))
         printf("  PP trial %d: %g\n",
                mPPTrialsToGo, thisTrial.ToSecondsSigDigits());
 
     if (--mPPTrialsToGo > 0)
         PingPongTrial();
     else
         Ping5Pong5Trial();
     return true;
@@ -92,28 +97,47 @@ TestLatencyParent::RecvPong5()
 {
     // HACK
     if (0 < --mPongsToGo)
         return true;
 
     TimeDuration thisTrial = (TimeStamp::Now() - mStart);
     mPP5TimeTotal += thisTrial;
 
-    if (0 == ((mPP5TrialsToGo % 1000)))
+    if (0 == (mPP5TrialsToGo % 1000))
         printf("  PP5 trial %d: %g\n",
                mPP5TrialsToGo, thisTrial.ToSecondsSigDigits());
 
     if (0 < --mPP5TrialsToGo)
         Ping5Pong5Trial();
     else
-        Exit();
+        RpcTrials();
 
     return true;
 }
 
+void
+TestLatencyParent::RpcTrials()
+{
+    for (int i = 0; i < NR_TRIALS; ++i) {
+        TimeStamp start = TimeStamp::Now();
+
+        if (!CallRpc())
+            fail("can't call Rpc()");
+
+        TimeDuration thisTrial = (TimeStamp::Now() - start);
+
+        if (0 == (i % 1000))
+            printf("  Rpc trial %d: %g\n", i, thisTrial.ToSecondsSigDigits());
+
+        mRpcTimeTotal += thisTrial;
+    }
+
+    Exit();
+}
 
 //-----------------------------------------------------------------------------
 // child
 
 TestLatencyChild::TestLatencyChild()
 {
     MOZ_COUNT_CTOR(TestLatencyChild);
 }
@@ -132,11 +156,16 @@ TestLatencyChild::RecvPing()
 
 bool
 TestLatencyChild::RecvPing5()
 {
     SendPong5();
     return true;
 }
 
+bool
+TestLatencyChild::AnswerRpc()
+{
+    return true;
+}
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/TestLatency.h
+++ b/ipc/ipdl/test/cxx/TestLatency.h
@@ -33,31 +33,36 @@ protected:
     virtual bool RecvPong5();
 
     NS_OVERRIDE
     virtual void ActorDestroy(ActorDestroyReason why)
     {
         if (NormalShutdown != why)
             fail("unexpected destruction!");  
 
-        passed("average ping/pong latency: %g sec, average ping5/pong5 latency: %g sec",
+        passed("average ping/pong latency: %g sec, "
+               "average ping5/pong5 latency: %g sec, "
+               "average RPC call/answer: %g sec",
                mPPTimeTotal.ToSecondsSigDigits() / (double) NR_TRIALS,
-               mPP5TimeTotal.ToSecondsSigDigits() / (double) NR_TRIALS);
+               mPP5TimeTotal.ToSecondsSigDigits() / (double) NR_TRIALS,
+               mRpcTimeTotal.ToSecondsSigDigits() / (double) NR_TRIALS);
 
         QuitParent();
     }
 
 private:
     void PingPongTrial();
     void Ping5Pong5Trial();
+    void RpcTrials();
     void Exit();
 
     TimeStamp mStart;
     TimeDuration mPPTimeTotal;
     TimeDuration mPP5TimeTotal;
+    TimeDuration mRpcTimeTotal;
 
     int mPPTrialsToGo;
     int mPP5TrialsToGo;
 
     // FIXME/cjones: HACK ALERT: don't need this once IPDL exposes actor state
     int mPongsToGo;
 };
 
@@ -69,16 +74,18 @@ public:
     TestLatencyChild();
     virtual ~TestLatencyChild();
 
 protected:
     NS_OVERRIDE
     virtual bool RecvPing();
     NS_OVERRIDE
     virtual bool RecvPing5();
+    NS_OVERRIDE
+    virtual bool AnswerRpc();
 
     NS_OVERRIDE
     virtual void ActorDestroy(ActorDestroyReason why)
     {
         if (NormalShutdown != why)
             fail("unexpected destruction!");
         QuitChild();
     }
--- a/ipc/ipdl/test/cxx/TestSyncWakeup.cpp
+++ b/ipc/ipdl/test/cxx/TestSyncWakeup.cpp
@@ -45,31 +45,33 @@ TestSyncWakeupParent::RecvSync1()
 
     // XXX ugh ... need to ensure that the async message and sync
     // reply come in "far enough" apart that this test doesn't pass on
     // accident
 #if defined(OS_POSIX)
     // NB: can't use PR_Sleep (i.e. Sleep() on windows) because it's
     // only spec'd to block the current thread, not the current
     // process.  We need the IO thread to sleep as well.
+    puts(" (sleeping for 5 seconds. sorry!)");
     sleep(5);
 #endif
 
     return true;
 }
 
 bool
 TestSyncWakeupParent::RecvSync2()
 {
     if (!SendNote2())
         fail("sending Note2()");
 
 #if defined(OS_POSIX)
     // see above
     sleep(5);
+    puts(" (sleeping for 5 seconds. sorry!)");
 #endif
 
     return true;
 }
 
 //-----------------------------------------------------------------------------
 // child