michael@0: _("Make sure lock prevents calling with a shared lock"); michael@0: Cu.import("resource://services-sync/util.js"); michael@0: michael@0: // Utility that we only use here. michael@0: michael@0: function do_check_begins(thing, startsWith) { michael@0: if (!(thing && thing.indexOf && (thing.indexOf(startsWith) == 0))) michael@0: do_throw(thing + " doesn't begin with " + startsWith); michael@0: } michael@0: michael@0: function run_test() { michael@0: let ret, rightThis, didCall; michael@0: let state, lockState, lockedState, unlockState; michael@0: let obj = { michael@0: _lock: Utils.lock, michael@0: lock: function() { michael@0: lockState = ++state; michael@0: if (this._locked) { michael@0: lockedState = ++state; michael@0: return false; michael@0: } michael@0: this._locked = true; michael@0: return true; michael@0: }, michael@0: unlock: function() { michael@0: unlockState = ++state; michael@0: this._locked = false; michael@0: }, michael@0: michael@0: func: function() this._lock("Test utils lock", michael@0: function() { michael@0: rightThis = this == obj; michael@0: didCall = true; michael@0: return 5; michael@0: })(), michael@0: michael@0: throwy: function() this._lock("Test utils lock throwy", michael@0: function() { michael@0: rightThis = this == obj; michael@0: didCall = true; michael@0: this.throwy(); michael@0: })() michael@0: }; michael@0: michael@0: _("Make sure a normal call will call and return"); michael@0: rightThis = didCall = false; michael@0: state = 0; michael@0: ret = obj.func(); michael@0: do_check_eq(ret, 5); michael@0: do_check_true(rightThis); michael@0: do_check_true(didCall); michael@0: do_check_eq(lockState, 1); michael@0: do_check_eq(unlockState, 2); michael@0: do_check_eq(state, 2); michael@0: michael@0: _("Make sure code that calls locked code throws"); michael@0: ret = null; michael@0: rightThis = didCall = false; michael@0: try { michael@0: ret = obj.throwy(); michael@0: do_throw("throwy internal call should have thrown!"); michael@0: } michael@0: catch(ex) { michael@0: // Should throw an Error, not a string. michael@0: do_check_begins(ex, "Could not acquire lock"); michael@0: } michael@0: do_check_eq(ret, null); michael@0: do_check_true(rightThis); michael@0: do_check_true(didCall); michael@0: _("Lock should be called twice so state 3 is skipped"); michael@0: do_check_eq(lockState, 4); michael@0: do_check_eq(lockedState, 5); michael@0: do_check_eq(unlockState, 6); michael@0: do_check_eq(state, 6); michael@0: }