Bug 765357 - Add xpcshell tests for the Profiler. r=ehsan
☠☠ backed out by e13388210fc2 ☠ ☠
authorBenoit Girard <b56girard@gmail.com>
Mon, 25 Jun 2012 16:49:41 -0400
changeset 97623 493781e75ced48565b48c193a7e10b9e7965b49a
parent 97622 aff898bb348b39ab68c8234c0c39009848f00c6d
child 97624 db9fc4c50e24f3a4080e1fc7299ffa79561e07f2
push idunknown
push userunknown
push dateunknown
reviewersehsan
bugs765357
milestone16.0a1
Bug 765357 - Add xpcshell tests for the Profiler. r=ehsan
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/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,8 @@
+[DEFAULT]
+head = head_profiler.js
+tail =
+
+[test_start.js]
+[test_get_features.js]
+[test_shared_library.js]
+[test_run.js]