api-power-monitor-spec.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. // eslint-disable-next-line no-undef
  108. let powerMonitor: typeof Electron.powerMonitor;
  109. before(() => {
  110. powerMonitor = require('electron').powerMonitor;
  111. });
  112. describe('powerMonitor.getSystemIdleState', () => {
  113. it('gets current system idle state', () => {
  114. // this function is not mocked out, so we can test the result's
  115. // form and type but not its value.
  116. const idleState = powerMonitor.getSystemIdleState(1);
  117. expect(idleState).to.be.a('string');
  118. const validIdleStates = [ 'active', 'idle', 'locked', 'unknown' ];
  119. expect(validIdleStates).to.include(idleState);
  120. });
  121. it('does not accept non positive integer threshold', () => {
  122. expect(() => {
  123. powerMonitor.getSystemIdleState(-1);
  124. }).to.throw(/must be greater than 0/);
  125. expect(() => {
  126. powerMonitor.getSystemIdleState(NaN);
  127. }).to.throw(/conversion failure/);
  128. expect(() => {
  129. powerMonitor.getSystemIdleState('a' as any);
  130. }).to.throw(/conversion failure/);
  131. });
  132. });
  133. describe('powerMonitor.getSystemIdleTime', () => {
  134. it('notify current system idle time', () => {
  135. const idleTime = powerMonitor.getSystemIdleTime();
  136. expect(idleTime).to.be.at.least(0);
  137. });
  138. });
  139. });
  140. });