Skip to content

Commit 2a14688

Browse files
vikaspotluri123acburdine
authored andcommitted
chore(tests) Add Systemd Process Manager tests (#544)
refs #541
1 parent 2ac0502 commit 2a14688

File tree

1 file changed

+341
-3
lines changed

1 file changed

+341
-3
lines changed
+341-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,346 @@
11
'use strict';
2+
const expect = require('chai').expect;
3+
const sinon = require('sinon');
4+
const proxyquire = require('proxyquire').noCallThru();
25

36
const modulePath = '../systemd';
7+
const errors = require('../../../lib/errors');
8+
const Systemd = require(modulePath);
49

5-
// TODO: remove line once tests are implemented
6-
require(modulePath);
10+
const instance = {
11+
name: 'ghost_org'
12+
};
713

8-
describe.skip('Unit: Systemd > Process Manager', function () {});
14+
function makeSystemd(options, ui) {
15+
let LocalSystem = Systemd;
16+
if (options !== null) {
17+
LocalSystem = proxyquire(modulePath, options);
18+
}
19+
return new LocalSystem(ui, null, instance);
20+
}
21+
22+
describe('Unit: Systemd > Process Manager', function () {
23+
it('Returns proper systemd name', function () {
24+
const ext = new Systemd(null, null, instance);
25+
26+
expect(ext.systemdName).to.equal('ghost_ghost_org');
27+
});
28+
29+
describe('Start Hook', function () {
30+
let ext, ui;
31+
32+
beforeEach(function () {
33+
ui = {sudo: sinon.stub().resolves()},
34+
ext = new Systemd(ui, null, instance);
35+
ext._precheck = () => true;
36+
});
37+
38+
it('Calls _precheck', function () {
39+
ext._precheck = sinon.stub();
40+
ext.start().then(() => {
41+
expect(ext._precheck.calledOnce).to.be.true;
42+
});
43+
});
44+
45+
it('Runs as sudo', function () {
46+
ext.start().then(() => {
47+
const expectedCmd = 'systemctl start ghost_ghost_org';
48+
expect(ui.sudo.calledOnce).to.be.true;
49+
expect(ui.sudo.getCall(0).args[0]).to.equal(expectedCmd);
50+
});
51+
});
52+
53+
it('Errors when sudo does', function () {
54+
ui.sudo = sinon.stub().rejects();
55+
ext.start().then(() => {
56+
expect(false, 'Promise should have rejected').to.be.true;
57+
}).catch((error) => {
58+
expect(error).to.be.ok;
59+
expect(ui.sudo.calledOnce).to.be.true;
60+
expect(error).to.be.instanceOf(errors.ProcessError);
61+
});
62+
});
63+
});
64+
65+
describe('Stop Hook', function () {
66+
let ext, ui;
67+
68+
beforeEach(function () {
69+
ui = {sudo: sinon.stub().resolves()},
70+
ext = new Systemd(ui, null, instance);
71+
ext._precheck = () => true;
72+
});
73+
74+
it('Calls _precheck', function () {
75+
ext._precheck = sinon.stub();
76+
ext.stop().then(() => {
77+
expect(ext._precheck.calledOnce).to.be.true;
78+
});
79+
});
80+
81+
it('Runs as sudo', function () {
82+
ext.stop().then(() => {
83+
const expectedCmd = 'systemctl stop ghost_ghost_org';
84+
expect(ui.sudo.calledOnce).to.be.true;
85+
expect(ui.sudo.getCall(0).args[0]).to.equal(expectedCmd);
86+
});
87+
});
88+
89+
it('Errors when sudo does', function () {
90+
ui.sudo = sinon.stub().rejects();
91+
ext.stop().then(() => {
92+
expect(false, 'Promise should have rejected').to.be.true;
93+
}).catch((error) => {
94+
expect(error).to.be.ok;
95+
expect(ui.sudo.calledOnce).to.be.true;
96+
expect(error).to.be.instanceOf(errors.ProcessError);
97+
});
98+
});
99+
});
100+
101+
describe('Restart Hook', function () {
102+
let ext, ui;
103+
104+
beforeEach(function () {
105+
ui = {sudo: sinon.stub().resolves()},
106+
ext = new Systemd(ui, null, instance);
107+
ext._precheck = () => true;
108+
});
109+
110+
it('Calls _precheck', function () {
111+
ext._precheck = sinon.stub();
112+
ext.restart().then(() => {
113+
expect(ext._precheck.calledOnce).to.be.true;
114+
});
115+
});
116+
117+
it('Runs as sudo', function () {
118+
ext.restart().then(() => {
119+
const expectedCmd = 'systemctl restart ghost_ghost_org';
120+
expect(ui.sudo.calledOnce).to.be.true;
121+
expect(ui.sudo.getCall(0).args[0]).to.equal(expectedCmd);
122+
});
123+
});
124+
125+
it('Errors when sudo does', function () {
126+
ui.sudo = sinon.stub().rejects();
127+
ext.restart().then(() => {
128+
expect(false, 'Promise should have rejected').to.be.true;
129+
}).catch((error) => {
130+
expect(error).to.be.ok;
131+
expect(ui.sudo.calledOnce).to.be.true;
132+
expect(error).to.be.instanceOf(errors.ProcessError);
133+
});
134+
});
135+
});
136+
137+
describe('isEnabled', function () {
138+
let execaStub;
139+
140+
beforeEach(function () {
141+
execaStub = sinon.stub();
142+
});
143+
144+
it('Calls execa', function () {
145+
const expectedCmd = 'systemctl is-enabled ghost_ghost_org';
146+
const ext = makeSystemd({execa: {shellSync: execaStub}});
147+
148+
expect(ext.isEnabled()).to.be.true;
149+
expect(execaStub.calledOnce).to.be.true;
150+
expect(execaStub.getCall(0).args[0]).to.equal(expectedCmd);
151+
});
152+
153+
it('Passes bad errors through', function () {
154+
execaStub = sinon.stub().throws(new Error('ponies'));
155+
const ext = makeSystemd({execa: {shellSync: execaStub}});
156+
157+
try {
158+
ext.isEnabled();
159+
expect(false, 'An error should have been thrown').to.be.true;
160+
} catch (error) {
161+
expect(execaStub.calledOnce).to.be.true;
162+
expect(error.message).to.equal('ponies');
163+
}
164+
});
165+
166+
it('Doesn\'t pass disabled errors through', function () {
167+
let execaStub = sinon.stub().throws(new Error('disabled'));
168+
const proxyOpts = {execa: {shellSync: execaStub}};
169+
let ext = makeSystemd(proxyOpts);
170+
171+
expect(ext.isEnabled()).to.be.false;
172+
173+
execaStub = sinon.stub().throws(new Error('Failed to get unit file state'));
174+
ext = makeSystemd(proxyOpts);
175+
176+
expect(ext.isEnabled()).to.be.false;
177+
});
178+
});
179+
180+
describe('enable', function () {
181+
it('Calls systemd', function () {
182+
const expectedCmd = 'systemctl enable ghost_ghost_org --quiet';
183+
const ui = {sudo: sinon.stub().resolves()};
184+
const ext = makeSystemd(null, ui);
185+
ext.enable().then(() => {
186+
expect(ui.sudo.calledOnce).to.be.true;
187+
expect(ui.sudo.getCall(0).args[0]).to.equal(expectedCmd);
188+
})
189+
});
190+
191+
it('Passes errors through', function () {
192+
const ui = {sudo: sinon.stub().rejects(new Error('red'))};
193+
const ext = makeSystemd(null, ui);
194+
ext.enable().then(() => {
195+
expect(false, 'Promise should have rejected').to.be.true;
196+
}).catch((error) => {
197+
expect(ui.sudo.calledOnce).to.be.true;
198+
expect(error).to.be.ok;
199+
expect(error).to.be.instanceOf(errors.ProcessError);
200+
});
201+
});
202+
});
203+
204+
describe('disable', function () {
205+
it('Calls systemd', function () {
206+
const expectedCmd = 'systemctl disable ghost_ghost_org --quiet';
207+
const ui = {sudo: sinon.stub().resolves()};
208+
const ext = makeSystemd(null, ui);
209+
ext.disable().then(() => {
210+
expect(ui.sudo.calledOnce).to.be.true;
211+
expect(ui.sudo.getCall(0).args[0]).to.equal(expectedCmd);
212+
})
213+
});
214+
215+
it('Passes errors through', function () {
216+
const ui = {sudo: sinon.stub().rejects(new Error('green'))};
217+
const ext = makeSystemd(null, ui);
218+
ext.disable().then(() => {
219+
expect(false, 'Promise should have rejected').to.be.true;
220+
}).catch((error) => {
221+
expect(ui.sudo.calledOnce).to.be.true;
222+
expect(error).to.be.ok;
223+
expect(error).to.be.instanceOf(errors.ProcessError);
224+
});
225+
});
226+
});
227+
228+
describe('isRunning', function () {
229+
let execaStub;
230+
231+
beforeEach(function () {
232+
execaStub = sinon.stub();
233+
});
234+
235+
it('Calls execa', function () {
236+
const expectedCmd = 'systemctl is-active ghost_ghost_org';
237+
const ext = makeSystemd({execa: {shellSync: execaStub}});
238+
239+
expect(ext.isRunning()).to.be.true;
240+
expect(execaStub.calledOnce).to.be.true;
241+
expect(execaStub.getCall(0).args[0]).to.equal(expectedCmd);
242+
});
243+
244+
it('Passes bad errors through', function () {
245+
execaStub = sinon.stub().throws(new Error('Zebra'));
246+
const ext = makeSystemd({execa: {shellSync: execaStub}});
247+
248+
try {
249+
ext.isRunning();
250+
expect(false, 'An error should have been thrown').to.be.true;
251+
} catch (error) {
252+
expect(execaStub.calledOnce).to.be.true;
253+
expect(error.message).to.equal('Zebra');
254+
}
255+
});
256+
257+
it('Doesn\'t pass stopped errors through', function () {
258+
let execaStub = sinon.stub().throws(new Error('inactive'));
259+
const proxyOpts = {execa: {shellSync: execaStub}};
260+
let ext = makeSystemd(proxyOpts);
261+
262+
expect(ext.isRunning()).to.be.false;
263+
264+
execaStub = sinon.stub().throws(new Error('activating'));
265+
ext = makeSystemd(proxyOpts);
266+
267+
expect(ext.isRunning()).to.be.false;
268+
});
269+
});
270+
271+
describe('_precheck', function () {
272+
let proxyOpts;
273+
274+
beforeEach(function () {
275+
proxyOpts = {'./get-uid': sinon.stub().returns(true)};
276+
});
277+
278+
it('Errors if uid doesn\'t been set', function () {
279+
proxyOpts['./get-uid'] = sinon.stub().returns(null);
280+
const ext = makeSystemd(proxyOpts);
281+
try {
282+
ext._precheck();
283+
expect(false, 'An error should have been thrown').to.be.true;
284+
} catch (error) {
285+
expect(proxyOpts['./get-uid'].calledOnce).to.be.true;
286+
expect(error).to.be.ok;
287+
expect(error).to.be.instanceOf(errors.SystemError);
288+
expect(error.message).to.match(/ghost setup linux-user systemd/);
289+
}
290+
});
291+
292+
it('Passes if unit file exists', function () {
293+
const fsStub = sinon.stub().returns(true);
294+
proxyOpts.fs = {existsSync: fsStub};
295+
const ext = makeSystemd(proxyOpts);
296+
const expectedFile = '/lib/systemd/system/ghost_ghost_org.service';
297+
298+
ext._precheck();
299+
expect(fsStub.calledOnce).to.be.true;
300+
expect(fsStub.getCall(0).args[0]).to.equal(expectedFile);
301+
});
302+
303+
it('Errors if unit file doesn\'t exist', function () {
304+
const fsStub = sinon.stub().returns(false);
305+
proxyOpts.fs = {existsSync: fsStub};
306+
const ext = makeSystemd(proxyOpts);
307+
308+
try {
309+
ext._precheck();
310+
expect(false, 'An error should have been thrown').to.be.true;
311+
} catch (error) {
312+
expect(fsStub.calledOnce).to.be.true;
313+
expect(error).to.be.ok;
314+
expect(error).to.be.instanceOf(errors.SystemError);
315+
expect(error.message).to.match(/ghost setup systemd/);
316+
}
317+
});
318+
});
319+
320+
describe('willRun', function () {
321+
let execaStub;
322+
323+
beforeEach(function () {
324+
execaStub = sinon.stub();
325+
});
326+
327+
it('Calls execa', function () {
328+
const expectedCmd = 'which systemctl';
329+
const Systemd = proxyquire(modulePath,
330+
{execa: {shellSync: execaStub}});
331+
332+
expect(Systemd.willRun()).to.be.true;
333+
expect(execaStub.calledOnce).to.be.true;
334+
expect(execaStub.getCall(0).args[0]).to.equal(expectedCmd);
335+
});
336+
337+
it('Always fails', function () {
338+
execaStub = sinon.stub().throws(new Error());
339+
const Systemd = proxyquire(modulePath,
340+
{execa: {shellSync: execaStub}});
341+
342+
expect(Systemd.willRun()).to.be.false;
343+
expect(execaStub.calledOnce).to.be.true;
344+
});
345+
});
346+
});

0 commit comments

Comments
 (0)