test_filesystemevents.js
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2009 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
27 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
28 
29 
30 function runTest()
31 {
32  // If the file-system watcher is not supported on this system, just return.
33  var fsWatcher = Cc["@songbirdnest.com/filesystem/watcher;1"]
34  .createInstance(Ci.sbIFileSystemWatcher);
35  if (!fsWatcher.isSupported) {
36  return;
37  }
38 
39  // To test the file system watcher, create a directory inside of the
40  // temporary working directory.
41 
42  // First, create the temporary directory.
43  var watchDir = Cc["@mozilla.org/file/directory_service;1"]
44  .getService(Ci.nsIProperties)
45  .get("ProfD", Ci.nsIFile);
46 
47  watchDir.normalize();
48  watchDir.append("watch_dir");
49  if (!watchDir.exists() || !watchDir.isDirectory()) {
50  watchDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
51  }
52 
53  var listener = new sbFSListener(watchDir, fsWatcher);
54  listener.startTest();
55 
56  testPending();
57 }
58 
59 
60 //
61 // \brief Create a FS listener with a directory to watch.
62 // \param aWatchDir The directory to watch (as nsIFile).
63 // \param aFSWatcher The FS watcher to use (sbIFileSystemWatcher).
64 //
65 function sbFSListener(aWatchDir, aFSWatcher)
66 {
67  this._watchDir = aWatchDir;
68  this._fsWatcher = aFSWatcher;
69 }
70 
71 sbFSListener.prototype =
72 {
73  _eventTimer: null,
74  _shutdownTimer: null,
75  _addedFile: null,
76  _changeFile: null,
77  _removeFile: null,
78  _receivedAddedEvent: false,
79  _receivedChangedEvent: false,
80  _receivedRemovedEvent: false,
81 
82  //
83  // \brief Start the listener and invoke a add, change, and remove event.
84  //
85  startTest: function()
86  {
87  this._log("Starting 'filesystemevents' test");
88 
89  this._addedFile = this._watchDir.clone();
90  this._addedFile.append("added.file");
91  if (this._addedFile.exists()) {
92  this._addedFile.remove(false);
93  }
94 
95  this._changeFile = this._watchDir.clone();
96  this._changeFile.append("changed.file");
97  if (!this._changeFile.exists()) {
98  this._changeFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0777);
99  }
100 
101  this._removeFile = this._watchDir.clone();
102  this._removeFile.append("removed.file");
103  if (!this._removeFile.exists()) {
104  this._removeFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0777);
105  }
106 
107  this._fsWatcher.init(this, this._watchDir.path, true);
108  this._fsWatcher.startWatching();
109  },
110 
111  _log: function(aMessage)
112  {
113  dump("----------------------------------------------------------\n");
114  dump(" " + aMessage + "\n");
115  dump("----------------------------------------------------------\n");
116  },
117 
118  // sbIFileSystemListener
119  onWatcherStarted: function()
120  {
121  this._log(" ... file system watcher started");
122 
123  // Wait at least 1 second to start the file system events.
124  this._eventTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
125  this._eventTimer.initWithCallback(this,
126  1000,
127  Ci.nsITimerCallback.TYPE_ONE_SHOT);
128  },
129 
130  onWatcherStopped: function()
131  {
132  this._log("... file system watcher has stopped");
133 
134  // Cleanup
135  this._addedFile.remove(false);
136  this._addedFile = null;
137 
138  this._removeFile = null;
139 
140  this._changeFile.remove(false);
141  this._changeFile = null;
142 
143  var retry = 5;
144  while (retry) {
145  try {
146  this._watchDir.remove(true);
147  this._watchDir = null;
148  retry = 0;
149  } catch (e) {
150  // Try a few more times, sometimes the watche doesn't clean up in time
151  --retry;
152  sleep(1000);
153  }
154  }
155  this._log("... ensuring events were received");
156 
157  // Ensure that all three of the events have been received.
158  assertTrue(this._receivedAddedEvent);
159  assertTrue(this._receivedChangedEvent);
160  assertTrue(this._receivedRemovedEvent);
161 
162  this._fsWatcher = null;
163  testFinished();
164  },
165 
166  onWatcherError: function(aErrorType, aDescription)
167  {
168  // Not used, but logging might be useful.
169  this._log("ERROR: [" + aErrorType + "] = " + aDescription + " !!!!!!!");
170  },
171 
172  onFileSystemChanged: function(aFilePath)
173  {
174  this._log("CHANGED: " + aFilePath);
175  this._receivedChangedEvent = true;
176  },
177 
178  onFileSystemRemoved: function(aFilePath)
179  {
180  this._log("REMOVED: " + aFilePath);
181  this._receivedRemovedEvent = true;
182  },
183 
184  onFileSystemAdded: function(aFilePath)
185  {
186  this._log("ADDED: " + aFilePath);
187  this._receivedAddedEvent = true;
188  },
189 
190  // nsITimerCallback
191  notify: function(aTimer)
192  {
193  if (aTimer == this._eventTimer) {
194  // Now create some events inside the test directory:
195 
196  // Add event:
197  this._addedFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0755);
198 
199  // Remove event:
200  this._removeFile.remove(false);
201 
202  // Changed event:
203  var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
204  .createInstance(Ci.nsIFileOutputStream);
205  foStream.init(this._changeFile, -1, -1, 0);
206  var junk = "garbage garbage garbage";
207  foStream.write(junk, junk.length);
208  foStream.close();
209 
210  // Setup a timer to wait to receive the events created above.
211  this._shutdownTimer = Cc["@mozilla.org/timer;1"]
212  .createInstance(Ci.nsITimer);
213  this._shutdownTimer.initWithCallback(this,
214  3000, // wait three seconds
215  Ci.nsITimerCallback.TYPE_ONE_SHOT);
216  }
217  else {
218  // The period to wait for file system events to be received has ended.
219  // Stop watching the directory and check the results in
220  // |onWatcherStopped()|.
221  this._fsWatcher.stopWatching(false);
222  }
223  },
224 
226  XPCOMUtils.generateQI( [Ci.sbIFileSystemListener, Ci.nsITimerCallback] )
227 };
228 
function sleep(ms, suppressOutput)
const Cc
function testFinished()
function sbFSListener(aWatchDir, aFSWatcher)
sbOSDControlService prototype QueryInterface
function assertTrue(aTest, aMessage)
TimerLoop prototype notify
function startTest()
return null
Definition: FeedWriter.js:1143
function runTest()
Advanced DataRemote unit tests.
function _log(aMsg, aMenuID)
const Ci
function testPending()