Skip to content

Commit 86fc898

Browse files
author
Dongsu Park
committed
dbus: add additional tests for dbus methods
Add additional unit tests for the following DBUS methods. * RestartUnit * TryRestartUnit * ReloadUnit * ReloadOrRestartUnit * ReloadOrTryRestartUnit * KillUnit * ResetFailedUnit * Reload
1 parent afdc6cc commit 86fc898

File tree

3 files changed

+386
-0
lines changed

3 files changed

+386
-0
lines changed

dbus/methods_test.go

Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import (
2222
"path"
2323
"path/filepath"
2424
"reflect"
25+
"syscall"
2526
"testing"
27+
"time"
2628

2729
"github.com/godbus/dbus"
2830
)
@@ -144,6 +146,252 @@ func TestStartStopUnit(t *testing.T) {
144146
}
145147
}
146148

149+
// Ensure that basic unit restarting works.
150+
func TestRestartUnit(t *testing.T) {
151+
target := "start-stop.service"
152+
conn := setupConn(t)
153+
154+
setupUnit(target, conn, t)
155+
linkUnit(target, conn, t)
156+
157+
// Start the unit
158+
reschan := make(chan string)
159+
_, err := conn.StartUnit(target, "replace", reschan)
160+
if err != nil {
161+
t.Fatal(err)
162+
}
163+
164+
job := <-reschan
165+
if job != "done" {
166+
t.Fatal("Job is not done:", job)
167+
}
168+
169+
units, err := conn.ListUnits()
170+
if err != nil {
171+
t.Fatal(err)
172+
}
173+
174+
unit := getUnitStatus(units, target)
175+
if unit == nil {
176+
t.Fatalf("Test unit not found in list")
177+
} else if unit.ActiveState != "active" {
178+
t.Fatalf("Test unit not active")
179+
}
180+
181+
// Restart the unit
182+
reschan = make(chan string)
183+
_, err = conn.RestartUnit(target, "replace", reschan)
184+
if err != nil {
185+
t.Fatal(err)
186+
}
187+
188+
job = <-reschan
189+
if job != "done" {
190+
t.Fatal("Job is not done:", job)
191+
}
192+
193+
// Stop the unit
194+
_, err = conn.StopUnit(target, "replace", reschan)
195+
if err != nil {
196+
t.Fatal(err)
197+
}
198+
199+
// wait for StopUnit job to complete
200+
<-reschan
201+
202+
units, err = conn.ListUnits()
203+
if err != nil {
204+
t.Fatal(err)
205+
}
206+
207+
unit = getUnitStatus(units, target)
208+
if unit != nil {
209+
t.Fatalf("Test unit found in list, should be stopped")
210+
}
211+
212+
// Try to restart the unit.
213+
// It should still succeed, even if the unit is inactive.
214+
reschan = make(chan string)
215+
_, err = conn.TryRestartUnit(target, "replace", reschan)
216+
if err != nil {
217+
t.Fatal(err)
218+
}
219+
220+
// wait for StopUnit job to complete
221+
<-reschan
222+
223+
units, err = conn.ListUnits()
224+
if err != nil {
225+
t.Fatal(err)
226+
}
227+
228+
unit = getUnitStatus(units, target)
229+
if unit != nil {
230+
t.Fatalf("Test unit found in list, should be stopped")
231+
}
232+
}
233+
234+
// Ensure that basic unit reloading works.
235+
func TestReloadUnit(t *testing.T) {
236+
target := "reload.service"
237+
conn := setupConn(t)
238+
239+
err := conn.Subscribe()
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
244+
subSet := conn.NewSubscriptionSet()
245+
evChan, errChan := subSet.Subscribe()
246+
247+
subSet.Add(target)
248+
249+
setupUnit(target, conn, t)
250+
linkUnit(target, conn, t)
251+
252+
// Start the unit
253+
reschan := make(chan string)
254+
_, err = conn.StartUnit(target, "replace", reschan)
255+
if err != nil {
256+
t.Fatal(err)
257+
}
258+
259+
job := <-reschan
260+
if job != "done" {
261+
t.Fatal("Job is not done:", job)
262+
}
263+
264+
units, err := conn.ListUnits()
265+
if err != nil {
266+
t.Fatal(err)
267+
}
268+
269+
unit := getUnitStatus(units, target)
270+
if unit == nil {
271+
t.Fatalf("Test unit not found in list")
272+
} else if unit.ActiveState != "active" {
273+
t.Fatalf("Test unit not active")
274+
}
275+
276+
// Reload the unit
277+
reschan = make(chan string)
278+
279+
_, err = conn.ReloadUnit(target, "replace", reschan)
280+
if err != nil {
281+
t.Fatal(err)
282+
}
283+
284+
job = <-reschan
285+
if job != "done" {
286+
t.Fatal("Job is not done:", job)
287+
}
288+
289+
timeout := make(chan bool, 1)
290+
go func() {
291+
time.Sleep(3 * time.Second)
292+
close(timeout)
293+
}()
294+
295+
// Wait for the event, expecting the target UnitStatus meets all of the
296+
// following conditions:
297+
// * target is non-nil
298+
// * target's ActiveState is active.
299+
waitevent:
300+
for {
301+
select {
302+
case changes := <-evChan:
303+
tch, ok := changes[target]
304+
if !ok {
305+
continue waitevent
306+
}
307+
if tch != nil && tch.Name == target && tch.ActiveState == "active" {
308+
break waitevent
309+
}
310+
case err = <-errChan:
311+
t.Fatal(err)
312+
case <-timeout:
313+
t.Fatal("Reached timeout")
314+
}
315+
}
316+
}
317+
318+
// Ensure that basic unit reload-or-restarting works.
319+
func TestReloadOrRestartUnit(t *testing.T) {
320+
target := "reload.service"
321+
conn := setupConn(t)
322+
323+
setupUnit(target, conn, t)
324+
linkUnit(target, conn, t)
325+
326+
// Start the unit
327+
reschan := make(chan string)
328+
_, err := conn.StartUnit(target, "replace", reschan)
329+
if err != nil {
330+
t.Fatal(err)
331+
}
332+
333+
job := <-reschan
334+
if job != "done" {
335+
t.Fatal("Job is not done:", job)
336+
}
337+
338+
units, err := conn.ListUnits()
339+
if err != nil {
340+
t.Fatal(err)
341+
}
342+
343+
unit := getUnitStatus(units, target)
344+
if unit == nil {
345+
t.Fatalf("Test unit not found in list")
346+
} else if unit.ActiveState != "active" {
347+
t.Fatalf("Test unit not active")
348+
}
349+
350+
// Reload or restart the unit
351+
reschan = make(chan string)
352+
_, err = conn.ReloadOrRestartUnit(target, "replace", reschan)
353+
if err != nil {
354+
t.Fatal(err)
355+
}
356+
357+
job = <-reschan
358+
if job != "done" {
359+
t.Fatal("Job is not done:", job)
360+
}
361+
362+
// Stop the unit
363+
_, err = conn.StopUnit(target, "replace", reschan)
364+
if err != nil {
365+
t.Fatal(err)
366+
}
367+
368+
// wait for StopUnit job to complete
369+
<-reschan
370+
371+
units, err = conn.ListUnits()
372+
if err != nil {
373+
t.Fatal(err)
374+
}
375+
376+
unit = getUnitStatus(units, target)
377+
if unit != nil && unit.ActiveState == "active" {
378+
t.Fatalf("Test unit still active, should be inactive.")
379+
}
380+
381+
// Reload or try to restart the unit
382+
// It should still succeed, even if the unit is inactive.
383+
reschan = make(chan string)
384+
_, err = conn.ReloadOrTryRestartUnit(target, "replace", reschan)
385+
if err != nil {
386+
t.Fatal(err)
387+
}
388+
389+
job = <-reschan
390+
if job != "done" {
391+
t.Fatal("Job is not done:", job)
392+
}
393+
}
394+
147395
// Ensure that ListUnitsByNames works.
148396
func TestListUnitsByNames(t *testing.T) {
149397
target1 := "systemd-journald.service"
@@ -538,6 +786,122 @@ func TestStartStopTransientScope(t *testing.T) {
538786
// int sd_pid_get_unit(pid_t pid, char **session)
539787
}
540788

789+
// Ensure that basic unit gets killed by SIGTERM
790+
func TestKillUnit(t *testing.T) {
791+
target := "start-stop.service"
792+
conn := setupConn(t)
793+
794+
err := conn.Subscribe()
795+
if err != nil {
796+
t.Fatal(err)
797+
}
798+
799+
subSet := conn.NewSubscriptionSet()
800+
evChan, errChan := subSet.Subscribe()
801+
802+
subSet.Add(target)
803+
804+
setupUnit(target, conn, t)
805+
linkUnit(target, conn, t)
806+
807+
// Start the unit
808+
reschan := make(chan string)
809+
_, err = conn.StartUnit(target, "replace", reschan)
810+
if err != nil {
811+
t.Fatal(err)
812+
}
813+
814+
job := <-reschan
815+
if job != "done" {
816+
t.Fatal("Job is not done:", job)
817+
}
818+
819+
// send SIGTERM
820+
conn.KillUnit(target, int32(syscall.SIGTERM))
821+
822+
timeout := make(chan bool, 1)
823+
go func() {
824+
time.Sleep(3 * time.Second)
825+
close(timeout)
826+
}()
827+
828+
// Wait for the event, expecting the target UnitStatus meets one of the
829+
// following conditions:
830+
// * target is nil, meaning the unit has completely gone.
831+
// * target is non-nil, and its ActiveState is not active.
832+
waitevent:
833+
for {
834+
select {
835+
case changes := <-evChan:
836+
tch, ok := changes[target]
837+
if !ok {
838+
continue waitevent
839+
}
840+
if tch == nil || (tch != nil && tch.Name == target && tch.ActiveState != "active") {
841+
break waitevent
842+
}
843+
case err = <-errChan:
844+
t.Fatal(err)
845+
case <-timeout:
846+
t.Fatal("Reached timeout")
847+
}
848+
}
849+
}
850+
851+
// Ensure that a failed unit gets reset
852+
func TestResetFailedUnit(t *testing.T) {
853+
target := "start-failed.service"
854+
conn := setupConn(t)
855+
856+
setupUnit(target, conn, t)
857+
linkUnit(target, conn, t)
858+
859+
// Start the unit
860+
reschan := make(chan string)
861+
_, err := conn.StartUnit(target, "replace", reschan)
862+
if err != nil {
863+
t.Fatal(err)
864+
}
865+
866+
job := <-reschan
867+
if job != "failed" {
868+
t.Fatal("Job is not failed:", job)
869+
}
870+
871+
units, err := conn.ListUnits()
872+
if err != nil {
873+
t.Fatal(err)
874+
}
875+
876+
unit := getUnitStatus(units, target)
877+
if unit == nil {
878+
t.Fatalf("Test unit not found in list")
879+
}
880+
881+
// reset the failed unit
882+
err = conn.ResetFailedUnit(target)
883+
if err != nil {
884+
t.Fatal(err)
885+
}
886+
887+
// Ensure that the target unit is actually gone
888+
units, err = conn.ListUnits()
889+
if err != nil {
890+
t.Fatal(err)
891+
}
892+
893+
found := false
894+
for _, u := range units {
895+
if u.Name == target {
896+
found = true
897+
break
898+
}
899+
}
900+
if found {
901+
t.Fatalf("Test unit still found in list. units = %v", units)
902+
}
903+
}
904+
541905
func TestConnJobListener(t *testing.T) {
542906
target := "start-stop.service"
543907
conn := setupConn(t)
@@ -620,3 +984,13 @@ func TestMaskUnmask(t *testing.T) {
620984
}
621985

622986
}
987+
988+
// Test a global Reload
989+
func TestReload(t *testing.T) {
990+
conn := setupConn(t)
991+
992+
err := conn.Reload()
993+
if err != nil {
994+
t.Fatal(err)
995+
}
996+
}

0 commit comments

Comments
 (0)