Browse Source

Add linux powerMonitor tests using python-dbusmock

Thiago de Arruda 7 years ago
parent
commit
dfd98e3428
4 changed files with 118 additions and 0 deletions
  1. 13 0
      script/lib/dbus_mock.py
  2. 14 0
      script/test.py
  3. 89 0
      spec/api-power-monitor-spec.js
  4. 2 0
      spec/package.json

+ 13 - 0
script/lib/dbus_mock.py

@@ -0,0 +1,13 @@
+from dbusmock import DBusTestCase
+
+import atexit
+
+def cleanup():
+    DBusTestCase.stop_dbus(DBusTestCase.system_bus_pid)
+
+
+atexit.register(cleanup)
+DBusTestCase.start_system_bus()
+# create a mock for "org.freedesktop.login1" using python-dbusmock
+# preconfigured template
+(logind_mock, logind) = DBusTestCase.spawn_server_template('logind')

+ 14 - 0
script/test.py

@@ -10,6 +10,20 @@ from lib.config import enable_verbose_mode
 from lib.util import electron_gyp, execute_stdout, rm_rf
 
 
+if sys.platform == 'linux2':
+    # On Linux we use python-dbusmock to create a fake system bus and test
+    # powerMonitor interaction with org.freedesktop.login1 service. The
+    # dbus_mock module takes care of setting up the fake server with mock,
+    # while also setting DBUS_SYSTEM_BUS_ADDRESS environment variable, which
+    # will be picked up by electron. 
+    try:
+        import lib.dbus_mock
+    except ImportError:
+        # If not available, the powerMonitor tests will be skipped since
+        # DBUS_SYSTEM_BUS_ADDRESS will not be set
+        pass
+
+
 SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
 
 PROJECT_NAME = electron_gyp()['project_name%']

+ 89 - 0
spec/api-power-monitor-spec.js

@@ -0,0 +1,89 @@
+// For these tests we use a fake DBus daemon to verify powerMonitor module
+// interaction with the system bus. This requires python-dbusmock installed and
+// running (with the DBUS_SYSTEM_BUS_ADDRESS environment variable set).
+// script/test.py will take care of spawning the fake DBus daemon and setting
+// DBUS_SYSTEM_BUS_ADDRESS when python-dbusmock is installed.
+//
+// See https://pypi.python.org/pypi/python-dbusmock for more information about
+// python-dbusmock.
+const assert = require('assert')
+const dbus = require('dbus-native')
+const Promise = require('bluebird')
+
+const skip = process.platform !== 'linux' || !process.env.DBUS_SYSTEM_BUS_ADDRESS;
+
+(skip ? describe.skip : describe)('powerMonitor', () => {
+  let logindMock, powerMonitor, getCalls, emitSignal, reset
+
+  before(async () => {
+    const systemBus = dbus.systemBus()
+    const loginService = systemBus.getService('org.freedesktop.login1')
+    const getInterface = Promise.promisify(loginService.getInterface, {context: loginService})
+    logindMock = await getInterface('/org/freedesktop/login1', 'org.freedesktop.DBus.Mock')
+    getCalls = Promise.promisify(logindMock.GetCalls, {context: logindMock})
+    emitSignal = Promise.promisify(logindMock.EmitSignal, {context: logindMock})
+    reset = Promise.promisify(logindMock.Reset, {context: logindMock})
+  })
+
+  after(async () => {
+    await reset()
+  })
+
+  describe('when powerMonitor module is loaded', () => {
+    function onceMethodCalled (done) {
+      function cb () {
+        logindMock.removeListener('MethodCalled', cb)
+      }
+      done()
+      return cb
+    }
+
+    before((done) => {
+      logindMock.on('MethodCalled', onceMethodCalled(done))
+      // lazy load powerMonitor after we listen to MethodCalled mock signal
+      powerMonitor = require('electron').remote.powerMonitor
+    })
+
+    it('should call Inhibit to delay suspend', async () => {
+      const calls = await getCalls()
+      assert.equal(calls.length, 1)
+      assert.deepEqual(calls[0].slice(1), [
+        'Inhibit', [
+          [[{type: 's', child: []}], ['sleep']],
+          [[{type: 's', child: []}], ['electron']],
+          [[{type: 's', child: []}], ['Application cleanup before suspend']],
+          [[{type: 's', child: []}], ['delay']]
+        ]
+      ])
+    })
+
+    describe('when PrepareForSleep(true) signal is sent by logind', () => {
+      it('should emit "suspend" event', (done) => {
+        powerMonitor.once('suspend', () => done())
+        emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
+          'b', [['b', true]])
+      })
+
+      describe('when PrepareForSleep(false) signal is sent by logind', () => {
+        it('should emit "resume" event', (done) => {
+          powerMonitor.once('resume', () => done())
+          emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
+            'b', [['b', false]])
+        })
+
+        it('should have called Inhibit again', async () => {
+          const calls = await getCalls()
+          assert.equal(calls.length, 2)
+          assert.deepEqual(calls[1].slice(1), [
+            'Inhibit', [
+              [[{type: 's', child: []}], ['sleep']],
+              [[{type: 's', child: []}], ['electron']],
+              [[{type: 's', child: []}], ['Application cleanup before suspend']],
+              [[{type: 's', child: []}], ['delay']]
+            ]
+          ])
+        })
+      })
+    })
+  })
+})

+ 2 - 0
spec/package.json

@@ -5,8 +5,10 @@
   "version": "0.1.0",
   "devDependencies": {
     "basic-auth": "^1.0.4",
+    "bluebird": "^3.5.1",
     "chai": "^4.1.2",
     "coffee-script": "1.12.7",
+    "dbus-native": "^0.2.3",
     "graceful-fs": "^4.1.9",
     "mkdirp": "^0.5.1",
     "mocha": "^3.1.0",