diff --git a/src/lib/dbus.ts b/src/lib/dbus.ts index 789ce268..d21f7b14 100644 --- a/src/lib/dbus.ts +++ b/src/lib/dbus.ts @@ -1,15 +1,13 @@ -import * as Bluebird from 'bluebird'; -import * as dbus from 'dbus'; +import { getBus, DBusError } from 'dbus'; +import { promisify } from 'util'; import { TypedError } from 'typed-error'; import log from './supervisor-console'; export class DbusError extends TypedError {} -const bus = dbus.getBus('system'); -const getInterfaceAsync = Bluebird.promisify(bus.getInterface, { - context: bus, -}); +const bus = getBus('system'); +const getInterfaceAsync = promisify(bus.getInterface.bind(bus)); async function getSystemdInterface() { try { @@ -19,7 +17,7 @@ async function getSystemdInterface() { 'org.freedesktop.systemd1.Manager', ); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -31,7 +29,7 @@ export async function getLoginManagerInterface() { 'org.freedesktop.login1.Manager', ); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -41,7 +39,7 @@ async function startUnit(unitName: string) { try { systemd.StartUnit(unitName, 'fail'); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -51,7 +49,7 @@ export async function restartService(serviceName: string) { try { systemd.RestartUnit(`${serviceName}.service`, 'fail'); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -69,7 +67,7 @@ async function stopUnit(unitName: string) { try { systemd.StopUnit(unitName, 'fail'); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -86,7 +84,7 @@ export async function enableService(serviceName: string) { try { systemd.EnableUnitFiles([`${serviceName}.service`], false, false); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } @@ -95,7 +93,7 @@ export async function disableService(serviceName: string) { try { systemd.DisableUnitFiles([`${serviceName}.service`], false); } catch (e) { - throw new DbusError(e); + throw new DbusError(e as DBusError); } } diff --git a/test/lib/mocked-dbus.ts b/test/lib/mocked-dbus.ts index f22ff232..1324cdb9 100644 --- a/test/lib/mocked-dbus.ts +++ b/test/lib/mocked-dbus.ts @@ -2,33 +2,66 @@ import * as dbus from 'dbus'; import { DBusError, DBusInterface } from 'dbus'; import { stub } from 'sinon'; +/** + * Because lib/dbus invokes dbus.getBus on module import, + * getBus needs to be stubbed at the root level due how JS + * `require` works. lib/dbus interfaces with the systemd and + * logind interfaces, which expose the unit methods below. + * + * There should be no need to un-stub dbus.getBus at any point + * during testing, since we never want to interact with the actual + * dbus system socket in the test environment. + * + * To test interaction with lib/dbus, import lib/dbus into the test suite + * and stub the necessary methods, as you would with any other module. + */ stub(dbus, 'getBus').returns({ getInterface: ( - _serviceName: string, + serviceName: string, _objectPath: string, _interfaceName: string, interfaceCb: (err: null | DBusError, iface: DBusInterface) => void, ) => { - interfaceCb(null, { - Get: ( - _unitName: string, - _property: string, - getCb: (err: null | Error, value: unknown) => void, - ) => { - getCb(null, 'this is the value'); - }, - GetUnit: ( - _unitName: string, - getUnitCb: (err: null | Error, unitPath: string) => void, - ) => { - getUnitCb(null, 'this is the unit path'); - }, - StartUnit: (_unitName: string) => { - // noop - }, - RestartUnit: (_unitName: string, _mode: string) => { - // noop - }, - } as any); + if (/systemd/.test(serviceName)) { + interfaceCb(null, { + StartUnit: () => { + // noop + }, + RestartUnit: () => { + // noop + }, + StopUnit: () => { + // noop + }, + EnableUnitFiles: () => { + // noop + }, + DisableUnitFiles: () => { + // noop + }, + GetUnit: ( + _unitName: string, + getUnitCb: (err: null | Error, unitPath: string) => void, + ) => { + getUnitCb(null, 'this is the unit path'); + }, + Get: ( + _unitName: string, + _property: string, + getCb: (err: null | Error, value: unknown) => void, + ) => { + getCb(null, 'this is the value'); + }, + } as any); + } else { + interfaceCb(null, { + Reboot: () => { + // noop + }, + PowerOff: () => { + // noop + }, + } as any); + } }, -} as any); +} as dbus.DBusConnection);