summaryrefslogtreecommitdiffstats
path: root/dom/plugins/test/mochitest/test_hang_submit.xul
blob: 6c037ecd49f473acd8cbef79e954ef1e51eeea36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                 type="text/css"?>
<window title="Basic Plugin Tests"
  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/javascript"
          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
  <script type="application/javascript"
          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
  <script type="application/javascript" src="plugin-utils.js"></script>
  <script type="application/javascript">
    setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
  </script>
<body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
<embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
SimpleTest.ignoreAllUncaughtExceptions();

Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");

var Cc = Components.classes;
var Ci = Components.interfaces;

const crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(Ci.nsICrashReporter);
const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";

var oldServerURL = crashReporter.serverURL;

const oldTimeoutPref = Services.prefs.getIntPref("dom.ipc.plugins.timeoutSecs");

var testObserver = {
  observe: function(subject, topic, data) {
    if (data == "submitting") // not done yet
      return;
    is(data, "success", "report should have been submitted successfully");
    is(topic, "crash-report-status", "Checking correct topic");
    ok(subject instanceof Ci.nsIPropertyBag2, "Subject should be a property bag");

    ok(subject.hasKey("minidumpID"), "Should have a local crash ID");
    let crashID = subject.getPropertyAsAString("minidumpID");
    isnot(crashID, "", "Local crash ID should not be an empty string");

    ok(subject.hasKey("serverCrashID"), "Should have a server crash ID");
    let remoteID = subject.getPropertyAsAString("serverCrashID");
    isnot(remoteID, "", "Server crash ID should not be an empty string");

    // Verify the data. The SJS script will return the data that was POSTed
    let req = new XMLHttpRequest();
    req.open("GET", SERVER_URL + "?id=" + remoteID, false);
    req.send(null);
    is(req.status, 200, "Server response should be 200 OK");
    let submitted = JSON.parse(req.responseText);

    ok(!("Throttleable" in submitted), "Submit request should not be Throttleable");
    is(submitted.ProcessType, "plugin", "Should specify ProcessType=plugin");
    ok("PluginHang" in submitted, "Request should contain PluginHang field");
    ok("additional_minidumps" in submitted, "Request should contain additional_minidumps field");
    let dumpNames = submitted.additional_minidumps.split(',');
    ok(dumpNames.indexOf("browser") != -1, "additional_minidumps should contain browser");
    info("additional_minidumps="+submitted.additional_minidumps);
    ok("upload_file_minidump" in submitted, "Request should contain upload_file_minidump field");
    ok("upload_file_minidump_browser" in submitted, "Request should contain upload_file_minidump_browser field");

    // Cleanup
    // First remove our fake submitted report
    let file = Services.dirsvc.get("UAppData", Ci.nsILocalFile);
    file.append("Crash Reports");
    file.append("submitted");
    file.append(remoteID + ".txt");
    file.remove(false);

    // Next unregister our observer
    Services.obs.removeObserver(testObserver, "crash-report-status");

    // Then re-set MOZ_CRASHREPORTER_NO_REPORT
    let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
    env.set("MOZ_CRASHREPORTER_NO_REPORT", "1");

    // Finally re-set prefs
    crashReporter.serverURL = oldServerURL;
    Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", oldTimeoutPref);

    // Check and cleanup CrashManager.
    Task.spawn(function* () {
      let cm = Services.crashmanager;
      let store = yield cm._getStore();
      is(store.crashesCount, 1, "Store should have only 1 item");

      let crash = store.getCrash(crashID);
      ok(!!crash, "Store should have the crash record");
      ok(crash.isOfType(cm.PROCESS_TYPE_PLUGIN, cm.CRASH_TYPE_HANG),
         "Crash type should be plugin-hang");
      is(crash.remoteID, remoteID, "Crash remoteID should match");

      is(crash.submissions.size, 1, "Crash should have a submission");
      let submission = crash.submissions.values().next().value;
      is(submission.result, cm.SUBMISSION_RESULT_OK,
         "Submission should be successful");

      store.reset();

      SimpleTest.finish();
    });
  },

  QueryInterface: function(iid) {
    if (iid.equals(Ci.nsIObserver) ||
        iid.equals(Ci.nsISupportsWeakReference) ||
        iid.equals(Ci.nsISupports))
      return this;
    throw Components.results.NS_NOINTERFACE;
  }
};

function onPluginCrashed(aEvent) {
  ok(true, "Plugin crashed notification received");
  is(aEvent.type, "PluginCrashed", "event is correct type");

  let submitButton = document.getAnonymousElementByAttribute(aEvent.target,
                                                             "class",
                                                             "submitButton");
  // try to submit this report
  sendMouseEvent({type:'click'}, submitButton, window);
}

function runTests() {
  // Default plugin hang timeout is too high for mochitests
  Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 1);

  // the test harness will have set MOZ_CRASHREPORTER_NO_REPORT,
  // ensure that we can change the setting and have our minidumps
  // wind up in Crash Reports/pending
  let env = Cc["@mozilla.org/process/environment;1"]
                      .getService(Ci.nsIEnvironment);
  env.set("MOZ_CRASHREPORTER_NO_REPORT", "");

  // Override the crash reporter URL to send to our fake server
  crashReporter.serverURL = NetUtil.newURI(SERVER_URL);

  // Hook into plugin crash events
  Services.obs.addObserver(testObserver, "crash-report-status", true);
  document.addEventListener("PluginCrashed", onPluginCrashed, false);

  var pluginElement = document.getElementById("plugin1");
  try {
    Task.spawn(function* () {
      // Clear data in CrashManager in case previous tests caused something
      // to be added.
      let store = yield Services.crashmanager._getStore();
      store.reset();

      pluginElement.hang();
    });
  } catch (e) {
  }
}
]]>
</script>
</window>