|
1 function create_subdir(dir, subdirname) { |
|
2 let subdir = dir.clone(); |
|
3 subdir.append(subdirname); |
|
4 if (subdir.exists()) { |
|
5 subdir.remove(true); |
|
6 } |
|
7 subdir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); |
|
8 return subdir; |
|
9 } |
|
10 |
|
11 // need to hold on to this to unregister for cleanup |
|
12 let _provider = null; |
|
13 |
|
14 function make_fake_appdir() { |
|
15 // Create a directory inside the profile and register it as UAppData, so |
|
16 // we can stick fake crash reports inside there. We put it inside the profile |
|
17 // just because we know that will get cleaned up after the mochitest run. |
|
18 let dirSvc = Cc["@mozilla.org/file/directory_service;1"] |
|
19 .getService(Ci.nsIProperties); |
|
20 let profD = dirSvc.get("ProfD", Ci.nsILocalFile); |
|
21 // create a subdir just to keep our files out of the way |
|
22 let appD = create_subdir(profD, "UAppData"); |
|
23 |
|
24 let crashesDir = create_subdir(appD, "Crash Reports"); |
|
25 create_subdir(crashesDir, "pending"); |
|
26 create_subdir(crashesDir, "submitted"); |
|
27 |
|
28 _provider = { |
|
29 getFile: function(prop, persistent) { |
|
30 persistent.value = true; |
|
31 if (prop == "UAppData") { |
|
32 return appD.clone(); |
|
33 } |
|
34 throw Components.results.NS_ERROR_FAILURE; |
|
35 }, |
|
36 QueryInterface: function(iid) { |
|
37 if (iid.equals(Ci.nsIDirectoryServiceProvider) || |
|
38 iid.equals(Ci.nsISupports)) { |
|
39 return this; |
|
40 } |
|
41 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
42 } |
|
43 }; |
|
44 // register our new provider |
|
45 dirSvc.QueryInterface(Ci.nsIDirectoryService) |
|
46 .registerProvider(_provider); |
|
47 // and undefine the old value |
|
48 try { |
|
49 dirSvc.undefine("UAppData"); |
|
50 } catch(ex) {} // it's ok if this fails, the value might not be cached yet |
|
51 return appD.clone(); |
|
52 } |
|
53 |
|
54 function cleanup_fake_appdir() { |
|
55 let dirSvc = Cc["@mozilla.org/file/directory_service;1"] |
|
56 .getService(Ci.nsIProperties); |
|
57 dirSvc.QueryInterface(Ci.nsIDirectoryService) |
|
58 .unregisterProvider(_provider); |
|
59 // undefine our value so future calls get the real value |
|
60 try { |
|
61 dirSvc.undefine("UAppData"); |
|
62 } catch(ex) { |
|
63 dump("cleanup_fake_appdir: dirSvc.undefine failed: " + ex.message +"\n"); |
|
64 } |
|
65 } |
|
66 |
|
67 function add_fake_crashes(crD, count) { |
|
68 let results = []; |
|
69 let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] |
|
70 .getService(Ci.nsIUUIDGenerator); |
|
71 let submitdir = crD.clone(); |
|
72 submitdir.append("submitted"); |
|
73 // create them from oldest to newest, to ensure that about:crashes |
|
74 // displays them in the correct order |
|
75 let date = Date.now() - count * 60000; |
|
76 for (let i = 0; i < count; i++) { |
|
77 let uuid = uuidGenerator.generateUUID().toString(); |
|
78 // ditch the {} |
|
79 uuid = "bp-" + uuid.substring(1, uuid.length - 2); |
|
80 let fn = uuid + ".txt"; |
|
81 let file = submitdir.clone(); |
|
82 file.append(fn); |
|
83 file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); |
|
84 file.lastModifiedTime = date; |
|
85 results.push({'id': uuid, 'date': date, 'pending': false}); |
|
86 |
|
87 date += 60000; |
|
88 } |
|
89 // we want them sorted newest to oldest, since that's the order |
|
90 // that about:crashes lists them in |
|
91 results.sort(function(a,b) b.date - a.date); |
|
92 return results; |
|
93 } |
|
94 |
|
95 function writeDataToFile(file, data) { |
|
96 var fstream = Cc["@mozilla.org/network/file-output-stream;1"] |
|
97 .createInstance(Ci.nsIFileOutputStream); |
|
98 // open, write, truncate |
|
99 fstream.init(file, -1, -1, 0); |
|
100 var os = Cc["@mozilla.org/intl/converter-output-stream;1"] |
|
101 .createInstance(Ci.nsIConverterOutputStream); |
|
102 os.init(fstream, "UTF-8", 0, 0x0000); |
|
103 os.writeString(data); |
|
104 os.close(); |
|
105 fstream.close(); |
|
106 } |
|
107 |
|
108 function addPendingCrashreport(crD, date, extra) { |
|
109 let pendingdir = crD.clone(); |
|
110 pendingdir.append("pending"); |
|
111 let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] |
|
112 .getService(Ci.nsIUUIDGenerator); |
|
113 let uuid = uuidGenerator.generateUUID().toString(); |
|
114 // ditch the {} |
|
115 uuid = uuid.substring(1, uuid.length - 1); |
|
116 let dumpfile = pendingdir.clone(); |
|
117 dumpfile.append(uuid + ".dmp"); |
|
118 writeDataToFile(dumpfile, "MDMP"); // that's the start of a valid minidump, anyway |
|
119 let extrafile = pendingdir.clone(); |
|
120 extrafile.append(uuid + ".extra"); |
|
121 let extradata = ""; |
|
122 for (let x in extra) { |
|
123 extradata += x + "=" + extra[x] + "\n"; |
|
124 } |
|
125 writeDataToFile(extrafile, extradata); |
|
126 dumpfile.lastModifiedTime = date; |
|
127 extrafile.lastModifiedTime = date; |
|
128 return {'id': uuid, 'date': date, 'pending': true, 'extra': extra}; |
|
129 } |