api-power-monitor-spec.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. import { expect } from 'chai'
  10. import * as dbus from 'dbus-native'
  11. import { ifdescribe } from './spec-helpers'
  12. import { promisify } from 'util'
  13. describe('powerMonitor', () => {
  14. let logindMock: any, dbusMockPowerMonitor: any, getCalls: any, emitSignal: any, reset: any
  15. // TODO(deepak1556): Enable on arm64 after upgrade, it crashes at the moment.
  16. ifdescribe(process.platform === 'linux' && process.arch !== 'arm64' && process.env.DBUS_SYSTEM_BUS_ADDRESS != null)('when powerMonitor module is loaded with dbus mock', () => {
  17. before(async () => {
  18. const systemBus = dbus.systemBus()
  19. const loginService = systemBus.getService('org.freedesktop.login1')
  20. const getInterface = promisify(loginService.getInterface.bind(loginService))
  21. logindMock = await getInterface('/org/freedesktop/login1', 'org.freedesktop.DBus.Mock')
  22. getCalls = promisify(logindMock.GetCalls.bind(logindMock))
  23. emitSignal = promisify(logindMock.EmitSignal.bind(logindMock))
  24. reset = promisify(logindMock.Reset.bind(logindMock))
  25. })
  26. after(async () => {
  27. await reset()
  28. })
  29. function onceMethodCalled (done: () => void) {
  30. function cb () {
  31. logindMock.removeListener('MethodCalled', cb)
  32. }
  33. done()
  34. return cb
  35. }
  36. before(done => {
  37. logindMock.on('MethodCalled', onceMethodCalled(done))
  38. // lazy load powerMonitor after we listen to MethodCalled mock signal
  39. dbusMockPowerMonitor = require('electron').powerMonitor
  40. })
  41. it('should call Inhibit to delay suspend', async () => {
  42. const calls = await getCalls()
  43. expect(calls).to.be.an('array').that.has.lengthOf(1)
  44. expect(calls[0].slice(1)).to.deep.equal([
  45. 'Inhibit', [
  46. [[{ type: 's', child: [] }], ['sleep']],
  47. [[{ type: 's', child: [] }], ['electron']],
  48. [[{ type: 's', child: [] }], ['Application cleanup before suspend']],
  49. [[{ type: 's', child: [] }], ['delay']]
  50. ]
  51. ])
  52. })
  53. describe('when PrepareForSleep(true) signal is sent by logind', () => {
  54. it('should emit "suspend" event', (done) => {
  55. dbusMockPowerMonitor.once('suspend', () => done())
  56. emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
  57. 'b', [['b', true]])
  58. })
  59. describe('when PrepareForSleep(false) signal is sent by logind', () => {
  60. it('should emit "resume" event', done => {
  61. dbusMockPowerMonitor.once('resume', () => done())
  62. emitSignal('org.freedesktop.login1.Manager', 'PrepareForSleep',
  63. 'b', [['b', false]])
  64. })
  65. it('should have called Inhibit again', async () => {
  66. const calls = await getCalls()
  67. expect(calls).to.be.an('array').that.has.lengthOf(2)
  68. expect(calls[1].slice(1)).to.deep.equal([
  69. 'Inhibit', [
  70. [[{ type: 's', child: [] }], ['sleep']],
  71. [[{ type: 's', child: [] }], ['electron']],
  72. [[{ type: 's', child: [] }], ['Application cleanup before suspend']],
  73. [[{ type: 's', child: [] }], ['delay']]
  74. ]
  75. ])
  76. })
  77. })
  78. })
  79. describe('when a listener is added to shutdown event', () => {
  80. before(async () => {
  81. const calls = await getCalls()
  82. expect(calls).to.be.an('array').that.has.lengthOf(2)
  83. dbusMockPowerMonitor.once('shutdown', () => { })
  84. })
  85. it('should call Inhibit to delay shutdown', async () => {
  86. const calls = await getCalls()
  87. expect(calls).to.be.an('array').that.has.lengthOf(3)
  88. expect(calls[2].slice(1)).to.deep.equal([
  89. 'Inhibit', [
  90. [[{ type: 's', child: [] }], ['shutdown']],
  91. [[{ type: 's', child: [] }], ['electron']],
  92. [[{ type: 's', child: [] }], ['Ensure a clean shutdown']],
  93. [[{ type: 's', child: [] }], ['delay']]
  94. ]
  95. ])
  96. })
  97. describe('when PrepareForShutdown(true) signal is sent by logind', () => {
  98. it('should emit "shutdown" event', done => {
  99. dbusMockPowerMonitor.once('shutdown', () => { done() })
  100. emitSignal('org.freedesktop.login1.Manager', 'PrepareForShutdown',
  101. 'b', [['b', true]])
  102. })
  103. })
  104. })
  105. })
  106. describe('when powerMonitor module is loaded', () => {
  107. let powerMonitor: typeof Electron.powerMonitor
  108. before(() => {
  109. powerMonitor = require('electron').powerMonitor
  110. })
  111. describe('powerMonitor.getSystemIdleState', () => {
  112. it('gets current system idle state', () => {
  113. // this function is not mocked out, so we can test the result's
  114. // form and type but not its value.
  115. const idleState = powerMonitor.getSystemIdleState(1)
  116. expect(idleState).to.be.a('string')
  117. const validIdleStates = [ 'active', 'idle', 'locked', 'unknown' ]
  118. expect(validIdleStates).to.include(idleState)
  119. })
  120. it('does not accept non positive integer threshold', () => {
  121. expect(() => {
  122. powerMonitor.getSystemIdleState(-1)
  123. }).to.throw(/must be greater than 0/)
  124. expect(() => {
  125. powerMonitor.getSystemIdleState(NaN)
  126. }).to.throw(/conversion failure/)
  127. expect(() => {
  128. powerMonitor.getSystemIdleState('a' as any)
  129. }).to.throw(/conversion failure/)
  130. })
  131. })
  132. describe('powerMonitor.getSystemIdleTime', () => {
  133. it('notify current system idle time', () => {
  134. const idleTime = powerMonitor.getSystemIdleTime()
  135. expect(idleTime).to.be.at.least(0)
  136. })
  137. })
  138. })
  139. })