Bug 765357 - Add xpcshell tests for the Profiler. r=ehsan
authorBenoit Girard <b56girard@gmail.com>
Tue, 26 Jun 2012 17:57:43 -0400
changeset 97750 3ee5063de5d557a45678038cfc47aeffc7c23fb6
parent 97749 77e2d6789e028135de5433c2e8003077be16edbf
child 97751 015b304bebd0332b71ecc595d5bbe8bdf29481ae
push id22993
push useremorley@mozilla.com
push dateWed, 27 Jun 2012 10:31:27 +0000
treeherdermozilla-central@1a56f1f011c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs765357
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 765357 - Add xpcshell tests for the Profiler. r=ehsan
testing/xpcshell/xpcshell.ini
tools/profiler/Makefile.in
tools/profiler/TableTicker.cpp
tools/profiler/nsIProfiler.idl
tools/profiler/nsProfiler.cpp
tools/profiler/tests/head_profiler.js
tools/profiler/tests/test_get_features.js
tools/profiler/tests/test_run.js
tools/profiler/tests/test_shared_library.js
tools/profiler/tests/test_start.js
tools/profiler/tests/xpcshell.ini
--- a/testing/xpcshell/xpcshell.ini
+++ b/testing/xpcshell/xpcshell.ini
@@ -119,8 +119,10 @@ run-if.config = ipc
 [include:modules/libpref/test/unit_ipc/xpcshell.ini]
 [include:netwerk/test/unit_ipc/xpcshell.ini]
 [include:netwerk/cookie/test/unit_ipc/xpcshell.ini]
 [include:toolkit/components/contentprefs/tests/unit_ipc/xpcshell.ini]
 [include:uriloader/exthandler/tests/unit_ipc/xpcshell.ini]
 
 [include:modules/libmar/tests/unit/xpcshell.ini]
 skip-if = os == "android"
+
+[include:tools/profiler/tests/xpcshell.ini]
--- a/tools/profiler/Makefile.in
+++ b/tools/profiler/Makefile.in
@@ -3,16 +3,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH       = ../..
 topsrcdir	  = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = $(srcdir)
+relativesrcdir = tools/profiler
+
+XPCSHELL_TESTS = tests
 
 include $(DEPTH)/config/autoconf.mk
 
 EXPORTS = sampler.h
 
 ifdef MOZ_ENABLE_PROFILER_SPS
 EXPORTS += \
   sps_sampler.h \
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -234,20 +234,19 @@ public:
 
     JSObject *profile = b.CreateObject();
     JSObject *samples = b.CreateArray();
     b.DefineProperty(profile, "samples", samples);
 
     JSObject *sample = NULL;
     JSObject *frames = NULL;
 
-    int oldReadPos = mReadPos;
-    while (mReadPos != mLastFlushPos) {
-      ProfileEntry entry = mEntries[mReadPos];
-      mReadPos = (mReadPos + 1) % mEntrySize;
+    int readPos = mReadPos;
+    while (readPos != mLastFlushPos) {
+      ProfileEntry entry = mEntries[readPos];
       switch (entry.mTagName) {
         case 's':
           sample = b.CreateObject();
           b.DefineProperty(sample, "name", (const char*)entry.mTagData);
           frames = b.CreateArray();
           b.DefineProperty(sample, "frames", frames);
           b.ArrayPush(samples, sample);
           break;
@@ -262,18 +261,18 @@ public:
               // extend 32-bit addresses starting with 0xFXXXXXX.
               unsigned long long pc = (unsigned long long)(uintptr_t)entry.mTagPtr;
               snprintf(tagBuff, 1024, "%#llx", pc);
               b.DefineProperty(frame, "location", tagBuff);
               b.ArrayPush(frames, frame);
             }
           }
       }
+      readPos = (readPos + 1) % mEntrySize;
     }
-    mReadPos = oldReadPos;
 
     return profile;
   }
 
   ProfileStack* GetStack()
   {
     return mStack;
   }
@@ -761,44 +760,53 @@ const char** mozilla_sampler_get_feature
 
   return features;
 }
 
 // Values are only honored on the first start
 void mozilla_sampler_start(int aProfileEntries, int aInterval,
                            const char** aFeatures, uint32_t aFeatureCount)
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   ProfileStack *stack = tlsStack.get();
   if (!stack) {
     ASSERT(false);
     return;
   }
 
   mozilla_sampler_stop();
 
   TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack,
                                    aFeatures, aFeatureCount);
   tlsTicker.set(t);
   t->Start();
 }
 
 void mozilla_sampler_stop()
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   TableTicker *t = tlsTicker.get();
   if (!t) {
     return;
   }
 
   t->Stop();
   delete t;
   tlsTicker.set(NULL);
 }
 
 bool mozilla_sampler_is_active()
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   TableTicker *t = tlsTicker.get();
   if (!t) {
     return false;
   }
 
   return t->IsActive();
 }
 
--- a/tools/profiler/nsIProfiler.idl
+++ b/tools/profiler/nsIProfiler.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
 #include "nsISupports.idl"
 
 [scriptable, uuid(e388fded-1321-41af-a988-861a2bc5cfc3)]
 interface nsIProfiler : nsISupports
 {
-  void StartProfiler(in PRUint32 aInterval, in PRUint32 aEntries,
+  void StartProfiler(in PRUint32 aEntries, in PRUint32 aInterval,
                       [array, size_is(aFeatureCount)] in string aFeatures,
                       in PRUint32 aFeatureCount);
   void StopProfiler();
   string GetProfile();
   [implicit_jscontext]
   jsval getProfileData();
   boolean IsActive();
   void GetResponsivenessTimes(out PRUint32 aCount, [retval, array, size_is(aCount)] out double aResult);
--- a/tools/profiler/nsProfiler.cpp
+++ b/tools/profiler/nsProfiler.cpp
@@ -21,20 +21,20 @@ NS_IMPL_ISUPPORTS1(nsProfiler, nsIProfil
 
 
 nsProfiler::nsProfiler()
 {
 }
 
 
 NS_IMETHODIMP
-nsProfiler::StartProfiler(PRUint32 aInterval, PRUint32 aEntries,
+nsProfiler::StartProfiler(PRUint32 aEntries, PRUint32 aInterval,
                           const char** aFeatures, PRUint32 aFeatureCount)
 {
-  SAMPLER_START(aInterval, aEntries, aFeatures, aFeatureCount);
+  SAMPLER_START(aEntries, aInterval, aFeatures, aFeatureCount);
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
   mozilla::InitEventTracing();
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsProfiler::StopProfiler()
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/head_profiler.js
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_get_features.js
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+  
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  var profilerFeatures = profiler.GetFeatures([]);
+  do_check_true(profilerFeatures != null);
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_run.js
@@ -0,0 +1,48 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  do_check_true(!profiler.IsActive());
+
+  profiler.StartProfiler(1000, 10, [], 0);
+
+  do_check_true(profiler.IsActive());
+
+  do_test_pending();
+
+  do_timeout(1000, function wait() {
+    // Check responsiveness
+    var resp = profiler.GetResponsivenessTimes({});
+    do_check_true(resp.length > 10);
+
+    // Check text profile format
+    var profileStr = profiler.GetProfile();
+    do_check_true(profileStr.length > 10);
+
+    // check json profile format
+    var profileObj = profiler.getProfileData();
+    do_check_neq(profileObj, null);
+    do_check_neq(profileObj.threads, null);
+    do_check_true(profileObj.threads.length >= 1);
+    do_check_neq(profileObj.threads[0].samples, null);
+    // NOTE: The number of samples will be empty since we
+    //       don't have any labels in the xpcshell code
+
+    profiler.StopProfiler();
+    do_check_true(!profiler.IsActive());
+    do_test_finished();
+  });
+
+
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_shared_library.js
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  var sharedStr = profiler.getSharedLibraryInformation();
+  sharedStr = sharedStr.toLowerCase();
+
+  // Let's not hardcode anything too specific
+  // just some sanity checks.
+  do_check_neq(sharedStr, null);
+  do_check_neq(sharedStr, "");
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_start.js
@@ -0,0 +1,25 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+  
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  do_check_true(!profiler.IsActive());
+
+  profiler.StartProfiler(10, 100, [], 0);
+
+  do_check_true(profiler.IsActive());
+
+  profiler.StopProfiler();
+
+  do_check_true(!profiler.IsActive());
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/xpcshell.ini
@@ -0,0 +1,10 @@
+[DEFAULT]
+head = head_profiler.js
+tail =
+
+[test_start.js]
+skip-if = true
+[test_get_features.js]
+[test_shared_library.js]
+[test_run.js]
+skip-if = true