Bug 1164130 - Correctly include RecordingUtils when importing older version 2 profiler data. r=vp, a=sledru
authorJordan Santell <jsantell@mozilla.com>
Tue, 12 May 2015 12:59:14 -0700
changeset 262367 b361f39e79d5c4de9f8b4ba9c1fb67df81cc0c6b
parent 262366 fc6d8e85c5c23117e208abc1ee368b123ed57162
child 262368 02659d1bb6499ca130e1c3367732b036100d646b
push id8059
push userbgrinstead@mozilla.com
push dateThu, 28 May 2015 03:50:58 +0000
treeherdermozilla-aurora@b104a8b24b27 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvp, sledru
bugs1164130
milestone40.0a2
Bug 1164130 - Correctly include RecordingUtils when importing older version 2 profiler data. r=vp, a=sledru
browser/devtools/performance/modules/io.js
browser/devtools/performance/modules/recording-utils.js
browser/devtools/performance/test/browser_perf_recordings-io-04.js
--- a/browser/devtools/performance/modules/io.js
+++ b/browser/devtools/performance/modules/io.js
@@ -2,16 +2,18 @@
  * 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/. */
 "use strict";
 
 const { Cc, Ci, Cu, Cr } = require("chrome");
 
 loader.lazyRequireGetter(this, "Services");
 loader.lazyRequireGetter(this, "promise");
+loader.lazyRequireGetter(this, "RecordingUtils",
+  "devtools/performance/recording-utils", true);
 
 loader.lazyImporter(this, "FileUtils",
   "resource://gre/modules/FileUtils.jsm");
 loader.lazyImporter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
 
 // This identifier string is used to tentatively ascertain whether or not
 // a JSON loaded from disk is actually something generated by this tool.
--- a/browser/devtools/performance/modules/recording-utils.js
+++ b/browser/devtools/performance/modules/recording-utils.js
@@ -259,16 +259,17 @@ exports.RecordingUtils.getFilteredBluepr
  */
 exports.RecordingUtils.deflateProfile = function deflateProfile(profile) {
   profile.threads = profile.threads.map((thread) => {
     let uniqueStacks = new UniqueStacks();
     return deflateThread(thread, uniqueStacks);
   });
 
   profile.meta.version = 3;
+  return profile;
 };
 
 /**
  * Given an array of frame objects, deduplicates each frame as well as all
  * prefixes in the stack. Returns the index of the deduplicated stack.
  *
  * @param object frames
  *               Array of frame objects.
--- a/browser/devtools/performance/test/browser_perf_recordings-io-04.js
+++ b/browser/devtools/performance/test/browser_perf_recordings-io-04.js
@@ -1,36 +1,94 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests if the performance tool can import profiler data from the
- * original profiler tool and the correct views and graphs are loaded.
+ * original profiler tool (Performance Recording v1, and Profiler data v2) and the correct views and graphs are loaded.
  */
+let { RecordingUtils } = devtools.require("devtools/performance/recording-utils");
+
+let TICKS_DATA = (function () {
+  let ticks = [];
+  for (let i = 0; i < 100; i++) {
+    ticks.push(i * 10);
+  }
+  return ticks;
+})();
+
+let PROFILER_DATA = (function () {
+  let data = {};
+  let threads = data.threads = [];
+  let thread = {};
+  threads.push(thread);
+  thread.name = "Content";
+  thread.samples = [{
+    time: 5,
+    frames: [
+      { location: "(root)" },
+      { location: "A" },
+      { location: "B" },
+      { location: "C" }
+    ]
+  }, {
+    time: 5 + 6,
+    frames: [
+      { location: "(root)" },
+      { location: "A" },
+      { location: "B" },
+      { location: "D" }
+    ]
+  }, {
+    time: 5 + 6 + 7,
+    frames: [
+      { location: "(root)" },
+      { location: "A" },
+      { location: "E" },
+      { location: "F" }
+    ]
+  }, {
+    time: 20,
+    frames: [
+      { location: "(root)" },
+      { location: "A" },
+      { location: "B" },
+      { location: "C" },
+      { location: "D" },
+      { location: "E" },
+      { location: "F" },
+      { location: "G" }
+    ]
+  }];
+
+  // Handled in other deflating tests
+  thread.markers = [];
+
+  let meta = data.meta = {};
+  meta.version = 2;
+  meta.interval = 1;
+  meta.stackwalk = 0;
+  meta.product = "Firefox";
+  return data;
+})();
 
 let test = Task.async(function*() {
   let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
   let { $, EVENTS, PerformanceController, DetailsView, OverviewView, JsCallTreeView } = panel.panelWin;
 
   // Enable memory to test the memory-calltree and memory-flamegraph.
   Services.prefs.setBoolPref(MEMORY_PREF, true);
 
-  yield startRecording(panel);
-  yield stopRecording(panel);
-
-  // Get data from the current profiler
-  let data = PerformanceController.getCurrentRecording().getAllData();
-
   // Create a structure from the data that mimics the old profiler's data.
   // Different name for `ticks`, different way of storing time,
   // and no memory, markers data.
   let oldProfilerData = {
-    profilerData: { profile: data.profile },
-    ticksData: data.ticks,
-    recordingDuration: data.duration,
+    profilerData: { profile: PROFILER_DATA },
+    ticksData: TICKS_DATA,
+    recordingDuration: 10000,
     fileType: "Recorded Performance Data",
     version: 1
   };
 
   // Save recording as an old profiler data.
   let file = FileUtils.getFile("TmpD", ["tmpprofile.json"]);
   file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
   yield asyncCopy(oldProfilerData, file);
@@ -59,39 +117,43 @@ let test = Task.async(function*() {
   is($("#select-js-flamegraph-view").hidden, false, "jsflamegraph button shown");
   is($("#select-memory-calltree-view").hidden, true, "memorycalltree button hidden");
   is($("#select-memory-flamegraph-view").hidden, true, "memoryflamegraph button hidden");
   ok(DetailsView.isViewSelected(JsCallTreeView), "jscalltree view selected as its the only option");
 
   // Verify imported recording.
 
   let importedData = PerformanceController.getCurrentRecording().getAllData();
+  let expected = Object.create({
+    label: "",
+    duration: 10000,
+    markers: [].toSource(),
+    frames: [].toSource(),
+    memory: [].toSource(),
+    ticks: TICKS_DATA.toSource(),
+    profile: RecordingUtils.deflateProfile(JSON.parse(JSON.stringify(PROFILER_DATA))).toSource(),
+    allocations: ({sites:[], timestamps:[], frames:[], counts:[]}).toSource(),
+    withTicks: true,
+    withMemory: false,
+    sampleFrequency: void 0
+  });
 
-  is(importedData.label, data.label,
-    "The imported legacy data was successfully converted for the current tool (1).");
-  is(importedData.duration, data.duration,
-    "The imported legacy data was successfully converted for the current tool (2).");
-  is(importedData.markers.toSource(), [].toSource(),
-    "The imported legacy data was successfully converted for the current tool (3).");
-  is(importedData.frames.toSource(), [].toSource(),
-    "The imported legacy data was successfully converted for the current tool (4).");
-  is(importedData.memory.toSource(), [].toSource(),
-    "The imported legacy data was successfully converted for the current tool (5).");
-  is(importedData.ticks.toSource(), data.ticks.toSource(),
-    "The imported legacy data was successfully converted for the current tool (6).");
-  is(importedData.allocations.toSource(), ({sites:[], timestamps:[], frames:[], counts:[]}).toSource(),
-    "The imported legacy data was successfully converted for the current tool (7).");
-  is(importedData.profile.toSource(), data.profile.toSource(),
-    "The imported legacy data was successfully converted for the current tool (8).");
-  is(importedData.configuration.withTicks, true,
-    "The imported legacy data was successfully converted for the current tool (9).");
-  is(importedData.configuration.withMemory, false,
-    "The imported legacy data was successfully converted for the current tool (10).");
-  is(importedData.configuration.sampleFrequency, void 0,
-    "The imported legacy data was successfully converted for the current tool (11).");
+  for (let field in expected) {
+    if (!!~["withTicks", "withMemory", "sampleFrequency"].indexOf(field)) {
+      is(importedData.configuration[field], expected[field], `${field} successfully converted in legacy import.`);
+    } else if (field === "profile") {
+      is(importedData.profile.toSource(), expected.profile,
+        `profiler data's samples successfully converted in legacy import.`);
+      is(importedData.profile.meta.version, 3, "Updated meta version to 3.");
+    } else {
+      let data = importedData[field];
+      is(typeof data === "object" ? data.toSource() : data, expected[field],
+        `${field} successfully converted in legacy import.`);
+    }
+  }
 
   yield teardown(panel);
   finish();
 });
 
 function getUnicodeConverter() {
   let className = "@mozilla.org/intl/scriptableunicodeconverter";
   let converter = Cc[className].createInstance(Ci.nsIScriptableUnicodeConverter);