api-power-monitor-spec.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // For these tests we use a fake DBus daemon to verify powerMonitor module
  2. // interaction with the system bus. This requires python-dbusmock installed and
  3. // running (with the DBUS_SYSTEM_BUS_ADDRESS environment variable set).
  4. // script/spec-runner.js will take care of spawning the fake DBus daemon and setting
  5. // DBUS_SYSTEM_BUS_ADDRESS when python-dbusmock is installed.
  6. //
  7. // See https://pypi.python.org/pypi/python-dbusmock for more information about
  8. // python-dbusmock.
  9. const chai = require('chai')
  10. const dirtyChai = require('dirty-chai')
  11. const dbus = require('dbus-native')
  12. const Promise = require('bluebird')
  13. const { expect } = chai
  14. chai.use(dirtyChai)
  15. const skip = process.platform !== 'linux' || !process.env.DBUS_SYSTEM_BUS_ADDRESS
  16. describe('powerMonitor', () => {
  17. let logindMock, dbusMockPowerMonitor, getCalls, emitSignal, reset
  18. if (!skip) {
  19. before(async () => {
  20. const systemBus = dbus.systemBus()
  21. const loginService = systemBus.getService('org.freedesktop.login1')
  22. const getInterface = Promise.promisify(loginService.getInterface, { context: loginService })
  23. logindMock = await getInterface('/org/freedesktop/login1', 'org.freedesktop.DBus.Mock')
  24. getCalls = Promise.promisify(logindMock.GetCalls, { context: logindMock })
  25. emitSignal = Promise.promisify(logindMock.EmitSignal, { context: logindMock })
  26. reset = Promise.promisify(logindMock.Reset, { context: logindMock })
  27. })
  28. after(async () => {
  29. await reset()
  30. })
  31. }
  32. (skip ? describe.skip : describe)('when powerMonitor module is loaded with dbus mock', () => {
  33. function onceMethodCalled (done) {
  34. function cb () {
  35. logindMock.removeListener('MethodCalled', cb)
  36. }
  37. done()
  38. return cb
  39. }
  40. before(done => {
  41. logindMock.on('MethodCalled', onceMethodCalled(done))
  42. // lazy load powerMonitor after we listen to MethodCalled mock signal
  43. dbusMockPowerMonitor = require('electron').remote.powerMonitor
  44. })
  45. it('should call Inhibit to delay suspend', async () => {
  46. const calls = await getCalls()
  47. expect(calls).to.be.an('array').that.has.lengthOf(1)
  48. expect(calls[0].slice(1)).to.deep.equal([
  49. 'Inhibit', [
  50. [[{ type: 's', child: [] }], ['sleep']],
  51. [[{ type: 's', child: [] }], ['electron']],
  52. [[{ type: 's', child: [] }], ['Application cleanup before suspend']],
  53. [[{ type: 's', child: [] }], ['delay']]
  54. ]
  55. ])
  56. })
  57. describe('when PrepareForSleep(true) signal is sent by logind', () => {
  58. it('should emit "suspend" event', (done) => {
  59. dbusMockPowerMonitor.once('suspend', () => done())
  60. emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
  61. 'b', [['b', true]])
  62. })
  63. describe('when PrepareForSleep(false) signal is sent by logind', () => {
  64. it('should emit "resume" event', done => {
  65. dbusMockPowerMonitor.once('resume', () => done())
  66. emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
  67. 'b', [['b', false]])
  68. })
  69. it('should have called Inhibit again', async () => {
  70. const calls = await getCalls()
  71. expect(calls).to.be.an('array').that.has.lengthOf(2)
  72. expect(calls[1].slice(1)).to.deep.equal([
  73. 'Inhibit', [
  74. [[{ type: 's', child: [] }], ['sleep']],
  75. [[{ type: 's', child: [] }], ['electron']],
  76. [[{ type: 's', child: [] }], ['Application cleanup before suspend']],
  77. [[{ type: 's', child: [] }], ['delay']]
  78. ]
  79. ])
  80. })
  81. })
  82. })
  83. describe('when a listener is added to shutdown event', () => {
  84. before(async () => {
  85. const calls = await getCalls()
  86. expect(calls).to.be.an('array').that.has.lengthOf(2)
  87. dbusMockPowerMonitor.once('shutdown', () => { })
  88. })
  89. it('should call Inhibit to delay shutdown', async () => {
  90. const calls = await getCalls()
  91. expect(calls).to.be.an('array').that.has.lengthOf(3)
  92. expect(calls[2].slice(1)).to.deep.equal([
  93. 'Inhibit', [
  94. [[{ type: 's', child: [] }], ['shutdown']],
  95. [[{ type: 's', child: [] }], ['electron']],
  96. [[{ type: 's', child: [] }], ['Ensure a clean shutdown']],
  97. [[{ type: 's', child: [] }], ['delay']]
  98. ]
  99. ])
  100. })
  101. describe('when PrepareForShutdown(true) signal is sent by logind', () => {
  102. it('should emit "shutdown" event', done => {
  103. dbusMockPowerMonitor.once('shutdown', () => { done() })
  104. emitSignal('org.freedesktop.login1.Manager', 'PrepareForShutdown',
  105. 'b', [['b', true]])
  106. })
  107. })
  108. })
  109. })
  110. describe('when powerMonitor module is loaded', () => {
  111. let powerMonitor
  112. before(() => {
  113. powerMonitor = require('electron').remote.powerMonitor
  114. })
  115. describe('powerMonitor.getSystemIdleState', () => {
  116. it('gets current system idle state', () => {
  117. // this function is not mocked out, so we can test the result's
  118. // form and type but not its value.
  119. const idleState = powerMonitor.getSystemIdleState(1)
  120. expect(idleState).to.be.a('string')
  121. const validIdleStates = [ 'active', 'idle', 'locked', 'unknown' ]
  122. expect(validIdleStates).to.include(idleState)
  123. })
  124. it('does not accept non positive integer threshold', () => {
  125. expect(() => {
  126. powerMonitor.getSystemIdleState(-1)
  127. }).to.throw(/must be greater than 0/)
  128. expect(() => {
  129. powerMonitor.getSystemIdleState(NaN)
  130. }).to.throw(/conversion failure/)
  131. expect(() => {
  132. powerMonitor.getSystemIdleState('a')
  133. }).to.throw(/conversion failure/)
  134. })
  135. })
  136. describe('powerMonitor.getSystemIdleTime', () => {
  137. it('notify current system idle time', () => {
  138. const idleTime = powerMonitor.getSystemIdleTime()
  139. expect(idleTime).to.be.at.least(0)
  140. })
  141. })
  142. })
  143. })