1
2
3
4
19
20 package systemd
21
22 import (
23 "context"
24 "fmt"
25 "testing"
26 "time"
27
28 "github.com/godbus/dbus/v5"
29 "github.com/stretchr/testify/assert"
30 )
31
32 type fakeDBusObject struct {
33 properties map[string]interface{}
34 bodyValue interface{}
35 }
36
37 func (obj *fakeDBusObject) Call(method string, flags dbus.Flags, args ...interface{}) *dbus.Call {
38 return &dbus.Call{Err: nil, Body: []interface{}{obj.bodyValue}}
39 }
40
41 func (obj *fakeDBusObject) CallWithContext(ctx context.Context, method string, flags dbus.Flags, args ...interface{}) *dbus.Call {
42 return nil
43 }
44
45 func (obj *fakeDBusObject) Go(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}) *dbus.Call {
46 return nil
47 }
48
49 func (obj *fakeDBusObject) GoWithContext(ctx context.Context, method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}) *dbus.Call {
50 return nil
51 }
52
53 func (obj *fakeDBusObject) AddMatchSignal(iface, member string, options ...dbus.MatchOption) *dbus.Call {
54 return nil
55 }
56
57 func (obj *fakeDBusObject) RemoveMatchSignal(iface, member string, options ...dbus.MatchOption) *dbus.Call {
58 return nil
59 }
60
61 func (obj *fakeDBusObject) GetProperty(p string) (dbus.Variant, error) {
62 value, ok := obj.properties[p]
63
64 if !ok {
65 return dbus.Variant{}, fmt.Errorf("property %q does not exist in properties: %+v", p, obj.properties)
66 }
67
68 return dbus.MakeVariant(value), nil
69 }
70
71 func (obj *fakeDBusObject) SetProperty(p string, v interface{}) error {
72 return nil
73 }
74
75 func (obj *fakeDBusObject) StoreProperty(p string, v interface{}) error {
76 return nil
77 }
78
79 func (obj *fakeDBusObject) Destination() string {
80 return ""
81 }
82
83 func (obj *fakeDBusObject) Path() dbus.ObjectPath {
84 return ""
85 }
86
87 type fakeSystemDBus struct {
88 fakeDBusObject *fakeDBusObject
89 signalChannel chan<- *dbus.Signal
90 }
91
92 func (f *fakeSystemDBus) Object(dest string, path dbus.ObjectPath) dbus.BusObject {
93 return f.fakeDBusObject
94 }
95
96 func (f *fakeSystemDBus) Signal(ch chan<- *dbus.Signal) {
97 f.signalChannel = ch
98 }
99
100 func (f *fakeSystemDBus) AddMatchSignal(options ...dbus.MatchOption) error {
101 return nil
102 }
103
104 func TestCurrentInhibitDelay(t *testing.T) {
105 thirtySeconds := time.Duration(30) * time.Second
106
107 bus := DBusCon{
108 SystemBus: &fakeSystemDBus{
109 fakeDBusObject: &fakeDBusObject{
110 properties: map[string]interface{}{
111 "org.freedesktop.login1.Manager.InhibitDelayMaxUSec": uint64(thirtySeconds / time.Microsecond),
112 },
113 },
114 },
115 }
116
117 delay, err := bus.CurrentInhibitDelay()
118 assert.NoError(t, err)
119 assert.Equal(t, thirtySeconds, delay)
120 }
121
122 func TestInhibitShutdown(t *testing.T) {
123 var fakeFd uint32 = 42
124
125 bus := DBusCon{
126 SystemBus: &fakeSystemDBus{
127 fakeDBusObject: &fakeDBusObject{
128 bodyValue: fakeFd,
129 },
130 },
131 }
132
133 fdLock, err := bus.InhibitShutdown()
134 assert.Equal(t, InhibitLock(fakeFd), fdLock)
135 assert.NoError(t, err)
136 }
137
138 func TestReloadLogindConf(t *testing.T) {
139 bus := DBusCon{
140 SystemBus: &fakeSystemDBus{
141 fakeDBusObject: &fakeDBusObject{},
142 },
143 }
144 assert.NoError(t, bus.ReloadLogindConf())
145 }
146
147 func TestMonitorShutdown(t *testing.T) {
148 var tests = []struct {
149 desc string
150 shutdownActive bool
151 }{
152 {
153 desc: "shutdown is active",
154 shutdownActive: true,
155 },
156 {
157 desc: "shutdown is not active",
158 shutdownActive: false,
159 },
160 }
161
162 for _, tc := range tests {
163 tc := tc
164 t.Run(tc.desc, func(t *testing.T) {
165 fakeSystemBus := &fakeSystemDBus{}
166 bus := DBusCon{
167 SystemBus: fakeSystemBus,
168 }
169
170 outChan, err := bus.MonitorShutdown()
171 assert.NoError(t, err)
172
173 done := make(chan bool)
174
175 go func() {
176 select {
177 case res := <-outChan:
178 assert.Equal(t, tc.shutdownActive, res)
179 done <- true
180 case <-time.After(5 * time.Second):
181 t.Errorf("Timed out waiting for shutdown message")
182 done <- true
183 }
184 }()
185
186 signal := &dbus.Signal{Body: []interface{}{tc.shutdownActive}}
187 fakeSystemBus.signalChannel <- signal
188 <-done
189 })
190 }
191 }
192
View as plain text