test_device_mock.js
Go to the documentation of this file.
1 /* vim: set sw=2 :miv */
2 /*
3  *=BEGIN SONGBIRD GPL
4  *
5  * This file is part of the Songbird web player.
6  *
7  * Copyright(c) 2005-2011 POTI, Inc.
8  * http://www.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 const TEST_RUNNING = 0;
27 const TEST_COMPLETED = 1;
28 const TEST_FAILED = 2;
29 
31 var testFailMessage = "";
32 
33 
38 function checkPropertyBag(aBag, aParams) {
39  for (var name in aParams) {
40  var val;
41  try {
42  val = aBag.getProperty(name);
43  } catch (e) {
44  log('Failed to get property "' + name + '"');
45  throw(e);
46  }
47  assertTrue(val, 'Cannot find property "' + name + '"');
48  if (typeof(aParams[name]) == "object" && "wrappedJSObject" in aParams[name])
49  val = val.wrappedJSObject;
50  assertEqual(aParams[name],
51  val,
52  'property "' + name + '" not equal');
53  log('"' + name + '" is ' + val);
54  }
55 }
56 
57 function runTest () {
58  let device = Components.classes["@songbirdnest.com/Songbird/Device/DeviceTester/MockDevice;1"]
59  .createInstance(Components.interfaces.sbIDevice);
60  // Check basic device properties
61  assertEqual(device.name, "Bob's Mock Device");
62  assertEqual(device.productName, "Mock Device");
63 
64  assertEqual("" + device.id, "" + device.id, "device ID not equal");
65  assertEqual("" + device.controllerId, "" + device.controllerId, "controller ID not equal");
66 
67  // Make sure device is initialized and disconnected on creation
68  assertFalse(device.connected);
69 
70  // Check connect
71  device.connect();
72  assertTrue(device.connected);
73 
74  // Attempt a reconnect, this is expected to throw, if it doesn't then that
75  // is a failure
76  try {
77  device.connect();
78  fail("Re-connected device");
79  } catch(e) {
80  /* expected to throw */
81  }
82 
83  // Make sure the device is still connected
84  assertTrue(device.connected);
85 
86  // For the rest of these tests we need to hook up a listener.
87  // If we shutdown before the device disconnects (disconnect is asynchronous)
88  // then we'll get a crash in GC land.
89  // This event handler checks testStatus to see if the test is currenly running
90  // or has failed or is completed. It is at the failed or completed state that
91  // the handler terminates the unit test.
92  device.QueryInterface(Components.interfaces.sbIDeviceEventTarget);
93  var handler = function handler(event) {
94  if (event.type == Ci.sbIDeviceEvent.EVENT_DEVICE_REMOVED) {
95 
96  // Check the current test status and end it if the test is done
97  switch (testStatus) {
98  case TEST_COMPLETED:
99  device.removeEventListener(handler);
100  //doTimeout(500, function() {
101  testFinished();
102  // return;
103  //});
104  return;
105  case TEST_FAILED:
106  device.removeEventListener(handler);
107  //doTimeout(500, function() {
109  // return;
110  //});
111  return;
112  case TEST_RUNNING:
113  // Continue and perform remaining tests
114  break;
115  default:
116  fail("Unexpected testStatus value: " + testStatus);
117  return;
118  }
119 
120  log("Device removed event fired");
121  try {
122  // Device was disconnected, continue on testing
123  assertFalse(device.connected);
124 
125  // Mock device is now threaded.
126  assertFalse(device.threaded);
127 
128  log("Reconnecting");
129  device.connect();
130 
131  test_prefs(device);
132 
133  /* TODO: device.capabilities */
134 
135  /* TODO: device.content */
136 
137  /* TODO: device.parameters */
138 
139  test_properties(device);
140 
141  test_event(device);
142 
147  function continueTest()
148  {
149  // Make sure we're connected
150  if (!device.connected)
151  device.connect();
152 
153  // Perform library and sync settings tests
154  try {
155  var operation = "test_library";
156  test_library(device);
157  operation = "test_sync_settings";
158  test_sync_settings(device);
160  }
161  catch (e) {
162  testFailMessage = operation + " failed with exception: " + e;
165  // stop a circular reference
166  if (device.connected)
167  device.disconnect();
168  }
169  finally {
170  if (testStatus != TEST_FAILED) {
172  }
173  // stop a circular reference
174  if (device.connected)
175  device.disconnect();
176  }
177  }
178  test_request(device, continueTest);
179  return;
180  }
181  catch (e) {
182  testFailMessage = "test_request failed with exception: " + e;
185  // stop a circular reference
186  if (device.connected) {
187  device.disconnect();
188  }
189  else {
190  fail();
191  return;
192  }
193  }
194  }
195  }
196  device.addEventListener(handler);
197 
198  device.disconnect();
199  try {
200  device.disconnect();
201  } catch(e) {
202  fail("Re-disconnected device should not fail");
203  }
204  testPending();
205 }
206 
207 function test_prefs(device) {
208  log("test_prefs");
209  assertTrue(typeof(device.getPreference("hello")) == "undefined");
210 
211  device.setPreference("world", 3);
212  assertEqual(device.getPreference("world"), 3);
213  assertEqual(typeof(device.getPreference("world")), "number");
214  device.setPreference("world", "goat");
215  assertEqual(device.getPreference("world"), "goat");
216  assertEqual(typeof(device.getPreference("world")), "string");
217  device.setPreference("world", true);
218  assertEqual(device.getPreference("world"), true);
219  assertEqual(typeof(device.getPreference("world")), "boolean");
220 
221  with (Components.interfaces.sbIDevice) {
222  device.setPreference("state", 0);
223  assertEqual(device.state, STATE_IDLE);
224  device.setPreference("state", 1);
225  assertEqual(device.state, STATE_SYNCING);
226  device.setPreference("state", 2);
227  assertEqual(device.state, STATE_COPYING);
228  device.setPreference("state", 3);
229  assertEqual(device.state, STATE_DELETING);
230  device.setPreference("state", 4);
231  assertEqual(device.state, STATE_UPDATING);
232  device.setPreference("state", 5);
233  assertEqual(device.state, STATE_MOUNTING);
234  device.setPreference("state", 6);
235  assertEqual(device.state, STATE_DOWNLOADING);
236  device.setPreference("state", 7);
237  assertEqual(device.state, STATE_UPLOADING);
238  device.setPreference("state", 8);
239  assertEqual(device.state, STATE_DOWNLOAD_PAUSED);
240  device.setPreference("state", 9);
241  assertEqual(device.state, STATE_UPLOAD_PAUSED);
242  device.setPreference("state", 10);
243  assertEqual(device.state, STATE_DISCONNECTED);
244  }
245 }
246 
247 function test_event(device) {
248  log("test_event");
249  /* test as a event target */
250  // I didn't bother with CI on the mock device
251  device.QueryInterface(Components.interfaces.sbIDeviceEventTarget);
252  var wasFired = false;
253  var handler = function handler() { wasFired = true; }
254  device.addEventListener(handler);
255  var event = Components.classes["@songbirdnest.com/Songbird/DeviceManager;2"]
256  .getService(Components.interfaces.sbIDeviceManager2)
257  .createEvent(0);
258  device.dispatchEvent(event);
259  assertTrue(wasFired, "event handler not called");
260 
261  device.removeEventListener(handler);
262 }
263 
264 function test_request(device, continueAction) {
265  log("test_request");
266  /* test as sbIMockDevice (request push/pop) */
267  device.QueryInterface(Ci.sbIMockDevice);
268 
269  // test the properties
270  var item = { QueryInterface:function(){return this} };
271  item.wrappedJSObject = item;
272  var list = { QueryInterface:function(){return this} };
273  list.wrappedJSObject = list;
274  var data = { /* nothing needed */ };
275  data.wrappedJSObject = data;
276  var params = { item: item,
277  list: list,
278  data: data,
279  index: 999,
280  otherIndex: 1024 };
281  var retryCount = 0;
282  device.submitRequest(0x201dbeef, createPropertyBag(params));
283  // Wait for a request to come in using a timeout
284  function requestCheck() {
285  let request = null;
286  try {
287  request = device.popRequest();
288  }
289  catch (e)
290  {
291  // exception expected, fall through with request being null
292  }
293  if (request) {
294  // Skip the thread start request and any other built in request
295  if (request.getProperty("requestType") >= 0x20000000) {
296  checkPropertyBag(request, params);
297  log("item transfer ID: " + request.getProperty("itemTransferID"));
298  assertTrue(request.getProperty("itemTransferID") > 3,
299  "Obviously bad item transfer ID");
300 
301  request = null; /* unleak */
302  continueAction();
303  return;
304  }
305  }
306  // Limit retries to 6 seconds
307  if (++retryCount > 60) {
308  fail("Failed in waiting for request");
309  }
310  // No request, continue to wait
311  doTimeout(100, requestCheck);
312  return;
313  }
314  doTimeout(100, requestCheck);
315 }
316 
317 function test_library(device) {
318  log("test_library");
319  assertEqual(
320  device,
321  device.content.libraries.queryElementAt(0, Ci.sbIDeviceLibrary).device);
322  assertTrue(device.defaultLibrary.equals(
323  device.content.libraries.queryElementAt(0, Ci.sbIDeviceLibrary)));
324 }
325 
326 function test_set_and_verify(device, audio, video, image)
327 {
328  let syncSettings = device.defaultLibrary.syncSettings;
329 
330  log("Changing management types to " + audio + ", " + video + ", " + image);
331 
332  // Get all the media settings
333  syncSettings = device.defaultLibrary.syncSettings;
334 
335  let audioSyncSettings = syncSettings.getMediaSettings(
336  Ci.sbIDeviceLibrary.MEDIATYPE_AUDIO);
337  let videoSyncSettings = syncSettings.getMediaSettings(
338  Ci.sbIDeviceLibrary.MEDIATYPE_VIDEO);
339  let imageSyncSettings = syncSettings.getMediaSettings(
340  Ci.sbIDeviceLibrary.MEDIATYPE_IMAGE);
341 
342  // Set the management types and verify
343  audioSyncSettings.mgmtType = audio;
344  assertEqual(audioSyncSettings.mgmtType, audio);
345  videoSyncSettings.mgmtType = video;
346  assertEqual(videoSyncSettings.mgmtType, video);
347  imageSyncSettings.mgmtType = image;
348  assertEqual(imageSyncSettings.mgmtType, image);
349 
350  device.defaultLibrary.syncSettings = syncSettings;
351 
352  // Now retrieve the media settings again and verify them
353  syncSettings = device.defaultLibrary.syncSettings;
354  assertEqual(syncSettings.getMediaSettings(
355  Ci.sbIDeviceLibrary.MEDIATYPE_AUDIO).mgmtType,
356  audio);
357  assertEqual(syncSettings.getMediaSettings(
358  Ci.sbIDeviceLibrary.MEDIATYPE_VIDEO).mgmtType,
359  video);
360  assertEqual(syncSettings.getMediaSettings(
361  Ci.sbIDeviceLibrary.MEDIATYPE_IMAGE).mgmtType,
362  image);
363  log("Checked Sync settings back");
364 }
365 
366 function test_sync_settings(device) {
367  log("Testing initial mode");
368  let syncSettings = device.defaultLibrary.syncSettings;
369 
370  log("Changing management type to all");
371  test_set_and_verify(device,
372  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_ALL,
373  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_ALL,
374  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_ALL);
375 
376  log("Changign management type to none");
377  test_set_and_verify(device,
378  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_NONE,
379  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_NONE,
380  Ci.sbIDeviceLibraryMediaSyncSettings.SYNC_MGMT_NONE);
381 }
382 
383 function test_properties(device) {
384  var properties = device.properties;
385 
386  log("friendlyName: " + properties.friendlyName);
387  assertEqual(properties.friendlyName, "Testing Device");
388  log("serialNumber: " + properties.serialNumber);
389  assertEqual(properties.serialNumber, "ACME-9000-0001-2000-3000");
390  log("modelNumber: " + properties.modelNumber);
391  assertEqual(properties.modelNumber, "ACME 9000");
392  log("vendorName: " + properties.vendorName);
393  assertEqual(properties.vendorName, "ACME Inc.");
394  log("firmwareVersion: " + properties.firmwareVersion);
395  assertEqual(properties.firmwareVersion, "1.0.0.0");
396 
397  properties.friendlyName = "New Friendly Test Device";
398  assertEqual(properties.friendlyName, "New Friendly Test Device");
399 }
400 
401 function createPropertyBag(aParams) {
402  var bag = Cc["@mozilla.org/hash-property-bag;1"]
403  .createInstance(Ci.nsIWritablePropertyBag);
404  for (var name in aParams) {
405  bag.setProperty(name, aParams[name]);
406  }
407  return bag;
408 }
const Cc
function fail(aMessage)
function log(s)
function testFinished()
const TEST_FAILED
var event
sbOSDControlService prototype QueryInterface
function assertTrue(aTest, aMessage)
function assertEqual(aExpected, aActual, aMessage)
const STATE_IDLE
const TEST_COMPLETED
function checkPropertyBag(aBag, aParams)
Device tests - Mock device.
const TEST_RUNNING
this _dialogInput val(dateText)
return null
Definition: FeedWriter.js:1143
function assertFalse(aTest, aMessage)
const Ci
var testFailMessage
function doTimeout(delay, func)
observe data
Definition: FeedWriter.js:1329
function runTest()
function createPropertyBag(aParams)
var testStatus
GstMessage gpointer data sbGStreamerMessageHandler * handler
function testPending()